我的应用程序采用以下方式启动服务: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”提示出现了,表明服务再次启动。 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}
如果我将 startService() 模式替换为 BIND_AUTO_CREATE,则问题不会出现(即使在仍绑定到服务的情况下崩溃应用程序)。如果我从未绑定到服务,它也可以正常工作。但是启动、绑定和解除绑定的组合似乎永远不会让我的服务死亡。在杀死应用程序之前使用 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