Mon application utilise un modèle où j'ai démarrer un service avec un Contexte#startService() ainsi que de la lier avec le Contexte#bindService(). C'est ainsi que je peux contrôler la durée de vie du service, indépendamment de savoir si tous les clients sont actuellement liés à elle. Cependant, j'ai remarqué récemment que chaque fois que mon application est tué par le système, il redémarre tous les services qui ont été en cours d'exécution. À ce stade, le service ne sera jamais dit d'arrêter, et c'est à l'origine de l'épuisement de la batterie à chaque fois que ça arrive. Voici un exemple minimal:
J'ai trouvé quelqu'un avec un problème similaire ici, mais ce n'était pas un diagnostic ou résolu.
Service:
@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();
}
Activité:
@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();
}
Pour le tester, j'ai lancé l'application, qui a commencé le service et lié à elle. Puis je l'ai retiré de l'app, qui se délie (mais quitte le service en cours d'exécution). Puis je l'ai fait
$ adb shell am kill com.tavianator.servicerestart
et bien sûr, 5 secondes plus tard, le "onCreate" toast s'affiche, indiquant que le service a commencé à nouveau. Logcat montre ceci:
$ 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}
Si je remplace la startService() modèle avec BIND_AUTO_CREATE, le problème ne se produit pas (même si je le plantage de l'application pendant qu'il est encore lié pour le service). Il fonctionne aussi si je n'ai jamais lier au service. Mais la combinaison de démarrer, de se lier et de délier semble ne jamais laisser mon service de mourir.
À l'aide de dumpsys avant de tuer l'application affiche ceci:
$ 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