为什么一个Android服务不测试的时候独居? [英] Why is an Android Service not singleton when testing?

查看:119
本文介绍了为什么一个Android服务不测试的时候独居?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在运行一大套的测试包,我发现我的Andr​​oid的服务之一是不是独居了。一个Android服务应该是单身,但使用ServiceTestCase时,我引用计数又大于1(递增的onCreate,递减的onDestroy)。 从测试用例调用startService或bindService应导致第二onBind或onStartCommand但不应该导致第一的onDestroy前第二的onCreate。

这是因为单元测试是绕过合子?如果是的话,我该如何解决这个问题?

解决方案
  

我发现我的Andr​​oid服务之一没有独居了

Android的服务是单身,无论你是否开始/绑定它实际运行环境下或在仪器测试。通过单,我的意思是唯一的对象居住在其中可以有多个引用指向它堆。

  

这是一个测试用例调用startService或bindService应导致第二onBind或onStartCommand

这是不正确的,因为在官方开发指南指出:多个客户端可以连接到服务一次不过,系统调用服务的onBind()方法来检索的IBinder的第一个客户端,只有当结合该系统将提供相同的IBinder到绑定任何其他客户端,而不调用onBind()了。

  

但第一次的onDestroy之前,不应该导致第二的onCreate

据官方开发指南:如果你允许你的服务要启动和约束,那么当该服务已启动,该系统不破坏服务时,所有客户端解除绑定,而是必须。明确停止服务,通过调用stopSelf()或stopService()。

所以幕后的情况下,通过第一次调用启动或绑定服务,Service.onCreate()方法被调用((之前调用要么onStartCommand()或onBind())在堆上创建一个唯一的对象并且对它的引用将返回(引用计数= 1),在这之后,每次调用启动或绑定服务,Service.onStartCommand()是不创建新的对象执行(通过调用Service.onCreate())在堆上,相反,返回第二参考指向同一个对象(现在的引用计数= 2),每次调用解除绑定,引用计数减一,直到引用计数达到0时,Service.onDestroy()方法被调用,最后清理堆中的对象。

您可以找到我的斜体引用从官方开发指南<一个所有细节href="http://developer.android.com/guide/topics/fundamentals/bound-services.html#Basics">here.

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.

这篇关于为什么一个Android服务不测试的时候独居?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆