我的应用程序使用一种模式,我使用Context#startService()启动服务并使用Context#bindService()绑定到它。这样我就可以独立于当前是否有任何客户端绑定到它来控制服务的生命周期。但是,我最近注意到,每当我的应用程序被系统杀死时,它很快就会重新启动所有正在运行的服务。此时将永远不会告诉服务停止,这会在发生时导致电池耗尽。这是一个最小的例子:
我在这里找到了有类似问题的人,但从未诊断或解决。
服务:
@Override
public void onCreate() {
Toast.makeText(this, "onCreate", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return new Binder();
}
活动:
@Override
protected void onStart() {
super.onStart();
Intent service = new Intent(this, BoundService.class);
startService(service);
bindService(service, mServiceConnection, 0);
}
@Override
protected void onStop() {
unbindService(mServiceConnection);
Toast.makeText(this, "unbindService", Toast.LENGTH_SHORT).show();
super.onStop();
}
为了测试它,我启动了应用程序,它启动了服务并绑定到它。然后我退出了应用程序,该应用程序解除绑定(但使服务保持运行)。然后我做了
$ adb shell am kill com.tavianator.servicerestart
果然,5秒后,“onCreate”toast出现了,说明服务又启动了。Logcat 显示了这一点:
$ adb logcat | grep BoundService
W/ActivityManager( 306): Scheduling restart of crashed service com.tavianator.servicerestart/.BoundService in 5000ms
I/ActivityManager( 306): Start proc com.tavianator.servicerestart for service com.tavianator.servicerestart/.BoundService: pid=20900 uid=10096 gids={1028}
如果我用 BIND_AUTO_CREATE 替换 startService() 模式,则不会发生问题(即使我在应用程序仍绑定到服务时崩溃)。如果我从不绑定到服务,它也可以工作。但是 start、bind 和 unbind 的组合似乎永远不会让我的服务死掉。
在杀死应用程序之前使用 dumpsys 显示:
$ adb shell dumpsys activity services com.tavianator.servicerestart
ACTIVITY MANAGER SERVICES (dumpsys activity services)
Active services:
* ServiceRecord{43099410 com.tavianator.servicerestart/.BoundService}
intent={cmp=com.tavianator.servicerestart/.BoundService}
packageName=com.tavianator.servicerestart
processName=com.tavianator.servicerestart
baseDir=/data/app/com.tavianator.servicerestart-2.apk
dataDir=/data/data/com.tavianator.servicerestart
app=ProcessRecord{424fb5c8 20473:com.tavianator.servicerestart/u0a96}
createTime=-20s825ms lastActivity=-20s825ms
executingStart=-5s0ms restartTime=-20s825ms
startRequested=true stopIfKilled=true callStart=true lastStartId=1
Bindings:
* IntentBindRecord{42e5e7c0}:
intent={cmp=com.tavianator.servicerestart/.BoundService}
binder=android.os.BinderProxy@42aee778
requested=true received=true hasBound=false doRebind=false