当运行大量测试套件时,我注意到我的一个Android服务不再是单例了。 Android服务应该是单例,但在使用ServiceTestCase时,我的引用计数超过1.(在onCreate中递增,在onDestroy中递减)。 从测试用例调用startService或bindService应该导致第二个onBind或onStartCommand,但是在第一个onDestroy之前不应该导致第二个onCreate。
这是因为单元测试绕过了Zygote吗?如果是这样,我该如何解决这个问题?
答案 0 :(得分:5)
我注意到我的一个Android服务不再是单例了
无论您是在真实运行环境下还是在仪器测试下启动/绑定,Android服务都是单例。单例,我指的是一个存在于堆中的唯一对象,它可以有多个引用指向它。
从测试用例调用startService或bindService应该导致第二个onBind或onStartCommand
这不是真的,如官方开发指南中所述:“多个客户端可以立即连接到服务。但是,系统调用您的服务的onBind()方法仅在第一个客户端时检索IBinder然后,系统将相同的IBinder传递给任何绑定的其他客户端,而无需再次调用onBind()。“
但在第一次onDestroy
之前永远不会导致第二次onCreate
根据官方开发指南:“如果您确实允许启动和绑定您的服务,那么当服务启动时,系统不会在所有客户端解除绑定时销毁服务。相反,您必须通过调用stopSelf()或stopService()来显式停止服务。“
所以幕后的场景是,第一次调用start或bind服务时,调用Service.onCreate()方法((在调用onStartCommand()或onBind()之前)在堆上创建一个唯一的对象并且返回对它的引用(引用计数= 1),之后,每次调用start或bind服务时,都会执行Service.onStartCommand()而不在堆上创建新对象(通过调用Service.onCreate()),相反,将第二个参考点返回到同一个对象(现在引用计数= 2),每次调用unbind时,引用计数减1,直到引用计数达到0,调用Service.onDestroy()方法并最终清理堆上的对象。
您可以从官方开发指南here找到我用斜体引用的所有详细信息。