В моем приложении используется шаблон, в котором я запускаю службу с Context # startService(), а также привязываюсь к ней с помощью Контекст # 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, проблема не возникает (даже если я врежу приложение, пока оно все еще связано с сервисом). Он также работает, если я никогда не свяжусь с сервисом. Но комбинация 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}
[email protected]
requested=true received=true hasBound=false doRebind=false