When running a large set of testsuites, I noticed that one of my Android Services isn't singleton anymore. An Android Service is supposed to be singleton but when using a ServiceTestCase my reference count went above 1. (incremented in onCreate, decremented in onDestroy).
Calling startService or bindService from a testcase should result in a second onBind or onStartCommand but should never result in a second onCreate before the first onDestroy.
Is this because the unit test is bypassing Zygote? And if so, how can I fix this?
I noticed that one of my Android Services isn't singleton anymore
Android Services is singleton regardless whether your start/bind it under real running environment or under instrumentation test. By singleton, I mean a unique object live in the heap which can have multiple references point to it.
Calling startService or bindService from a testcase should result in a second onBind or onStartCommand
this is not true, as stated in the official dev guide: "Multiple clients can connect to the service at once. However, the system calls your service's onBind() method to retrieve the IBinder only when the first client binds. The system then delivers the same IBinder to any additional clients that bind, without calling onBind() again."
but should never result in a second onCreate before the first onDestroy
According to the official dev guide: "If you do allow your service to be started and bound, then when the service has been started, the system does not destroy the service when all clients unbind. Instead, you must explicitly stop the service, by calling stopSelf() or stopService()."
So the scenario behind the scenes is, by first time you call start or bind service, Service.onCreate() method is called ((before calling either onStartCommand() or onBind()) to create a unique object on the heap and a reference to it is returned (reference count = 1), after that, each time you call start or bind service, Service.onStartCommand() is perform without creating new object (by calling Service.onCreate()) on the heap, instead, return a second reference point to the same object (now reference count = 2), each time you call unbind, reference count decrease by one, until reference count reach to 0, Service.onDestroy() method is called and finally clean up the object on the heap.
You can find all details I referenced in italic from the official dev guide here.