我有一个简单的 ServiceTestCase 和一个仅包含生命周期方法的空 IntentSerice,该服务也注册了 AndroidManifest.xml,以及一个操作标签“com.tut.my.service.DATAUPDATE”。
Service 的调用效果很好,所有的 live-cycle 方法都按顺序出现,但是在我的自定义测试完成后发生了一些奇怪的事情。ServiceTestCase 在我的自定义测试之后发布了方法testServiceTestCaseSetUpProperly()以确保setupService()正确运行。
所以我环顾四周,发现一些有趣的博客关注 setupService(),但结论并不令人满意。博客作者建议 - 出于某种充分的理由 - 不要在setUp()中调用startService(...),因为他非常清楚为什么这不是一个好主意。
但是,在我的自定义测试之后调用 testServiceTestCaseSetUpProperly() 给我带来的问题是调用 MyService 服务的新实例。这最终会调用 onCreate 并且服务由于某种原因而死,finito ...但所有测试都成功通过。
这是服务的来源:
public class MyService extends IntentService {
public static final String INTENT = "com.tut.my.service.DATAUPDATE";
public MyService() {
super(INTENT);
Log.d(getClass().getSimpleName(), "called: std c-tor()");
}
@Override
public void onCreate() {
super.onCreate();
Log.d(getClass().getSimpleName(), "called: onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(getClass().getSimpleName(), "called onStartCommand() --> intent: " + intent.getAction() + " flags: " + flags + " startID: " + startId);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(getClass().getSimpleName(),"called: onDestory()");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(getClass().getSimpleName(), "called: onHandleIntent() --> Intent: " + intent.getAction());
setPriceData();
}
}
这是 ServiceTestCase 的来源
@MediumTest
public class MyServiceTest extends ServiceTestCase<MyService> {
Context mCtx = null;
public MyServiceTest() {
super(MyService.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mCtx = getSystemContext();
}
@MediumTest
public void testGetMyServiceData() throws InterruptedException {
Intent i = new Intent(MyService.INTENT);
Log.d(getClass().getSimpleName(), "startService(i)");
mCtx.startService(i);
// throttle the instrumentation thread so the service
// can be instantiated for sure
Log.d(getClass().getSimpleName(), "before Thread Sleep");
Thread.sleep(8000); // needs 10 seconds before ANR
Log.d(getClass().getSimpleName(), "after Thread Sleep");
}
}
以及相应的(剥离的)LogCat 输出:
I/TestRunner(11954): started: testGetMyServiceData(com.tut.my.service.MyServiceTest)
D/MyServiceTest(11954): startService(i)
D/MyService(11954): called: std c-tor()
D/MyServiceTest(11954): before Thread Sleep
D/MyService(11954): called: onCreate()
D/MyService(11954): called onStartCommand() --> intent: com.tut.my.service.DATAUPDATE flags: 0 startID: 1
D/MyService(11954): called: onHandleIntent() --> Intent: com.tut.my.service.DATAUPDATE
D/MyService(11954): called: onDestory()
D/MyServiceTest(11954): after Thread Sleep
I/TestRunner(11954): finished: testGetMyServiceData(com.tut.my.service.MyServiceTest)
I/TestRunner(11954): passed: testGetHarvestData(com.tut.my.service.MyServiceTest)
I/TestRunner(11954): started: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest)
D/MyService(11954): called: std c-tor()
I/TestRunner(11954): finished: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest)
I/TestRunner(11954): passed: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest)
I/TestRunner(11954): started: testAndroidTestCaseSetupProperly(com.tut.my.service.MyServiceTest)
I/TestRunner(11954): finished: testAndroidTestCaseSetupProperly(com.tut.my.service.MyServiceTest)
I/TestRunner(11954): passed: testAndroidTestCaseSetupProperly(com.tut.my.service.MyServiceTest)
I/ActivityManager(71): Force stopping package com.tut.my.service uid=10036
I/Process(71): Sending signal. PID: 11954 SIG: 9
所以问题是,为什么 testServiceTestCaseSetupProperly() 在最后而不是首先被调用?以及为什么 MyService 对象如此不优雅地死去。
编辑:为了更精确:
我关心的重要部分是对 onCreate 的粗鲁调用。
I/TestRunner(11954): started: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest)
D/MyService(11954): called: std c-tor() <--- ONLY one call to onCreate
I/TestRunner(11954): finished:testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest)
- 如果我要在 onCreate 中分配资源,谁断言我要清理分配的资源?
- 为什么在所有测试结束时开始检查正确的服务设置?
- 为什么它会被杀死呢?