START_STICKY et START_NOT_STICKY

Réponses:

371

Les deux codes ne sont pertinents que lorsque le téléphone manque de mémoire et tue le service avant de terminer son exécution. START_STICKYindique au système d'exploitation de recréer le service une fois qu'il a suffisamment de mémoire et d'appeler à onStartCommand()nouveau avec une intention nulle. START_NOT_STICKYindique au système d'exploitation de ne pas se soucier de recréer le service à nouveau. Il existe également un troisième code START_REDELIVER_INTENTqui indique au système d'exploitation de recréer le service et de livrer à nouveau la même intention onStartCommand().

Cet article de Dianne Hackborn en a expliqué le contexte bien mieux que la documentation officielle.

Source: http://android-developers.blogspot.com.au/2010/02/service-api-changes-starting-with.html

La partie clé ici est un nouveau code de résultat renvoyé par la fonction, indiquant au système ce qu'il doit faire avec le service si son processus est tué pendant son exécution:

START_STICKY est fondamentalement le même que le comportement précédent, où le service est laissé "démarré" et sera ensuite redémarré par le système. La seule différence avec les versions précédentes de la plate-forme est que si elle est redémarrée parce que son processus est tué, onStartCommand () sera appelé sur la prochaine instance du service avec une intention nulle au lieu de ne pas être appelé du tout. Les services qui utilisent ce mode doivent toujours vérifier ce cas et le traiter de manière appropriée.

START_NOT_STICKY indique que, après le retour de onStartCreated (), si le processus est tué sans aucune commande de démarrage restante à livrer, le service sera arrêté au lieu d'être redémarré. Cela a beaucoup plus de sens pour les services qui sont destinés à s'exécuter uniquement lors de l'exécution des commandes qui leur sont envoyées. Par exemple, un service peut être démarré toutes les 15 minutes à partir d'une alarme pour interroger un état du réseau. S'il est tué en faisant ce travail, il serait préférable de le laisser s'arrêter et de démarrer la prochaine fois que l'alarme se déclenche.

START_REDELIVER_INTENT est comme START_NOT_STICKY, sauf si le processus du service est tué avant d'appeler stopSelf () pour une intention donnée, cette intention lui sera restituée jusqu'à ce qu'elle se termine (sauf si après un certain nombre d'essais supplémentaires, elle ne peut toujours pas se terminer, à quel moment le système abandonne). Cela est utile pour les services qui reçoivent des commandes de travail à effectuer et qui souhaitent s'assurer qu'ils finissent par terminer le travail pour chaque commande envoyée.

Frank Leigh
la source
1
Comment éviter le double appel à la tâche handleStart (intention, startId); comme onStart () et onStartCommand seront appelés? est-ce un bon design? @Frank Leigh
Sazzad Hissain Khan
2
Quel est le drapeau par défaut, cependant, si aucun n'est spécifié?
IgorGanapolsky
3
Si vous suivez le "return super.onStartCommand (...);" vous verrez que dans le cas où votre version sdk cible est inférieure à ECLAIR (API5 = 2.0) par défaut, la START_STICKY_COMPATIBILITY est renvoyée et à partir de la version 2.0, START_STICKY est retournée.
MikeL
1
Qu'entendez-vous par «sans aucune commande de démarrage restante» dans START_NOT_STICKY?
Malwinder Singh
3
@FrankLeigh Je ne suis pas d'accord pour dire que START_REDELIVER_INTENTc'est comme START_NOT_STICKY. Au lieu de cela, c'est commeSTART_STICKY
CopsOnRoad
107

Réponse KISS

Différence:

START_STICKY

le système essaiera de recréer votre service après sa mort

START_NOT_STICKY

le système n'essaiera pas de recréer votre service après sa mort


Exemple standard:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}
Breed Oded
la source
5
En fait, ce n'est pas correct et déroutant. C'est une erreur de dire: "le service est tué" car on peut penser que vous vous référez à stopSelf ou stopService, alors que vous faites évidemment référence au processus tué. Il vaut donc mieux utiliser le traitement de texte dans votre réponse.
Ilya Gazman
Salut comment je peux tester START_REDELIVER_INTENT. Je viens de tester START_STICKYet de tuer l'application par des applications récentes. Ensuite, il rappelle le service. Mais START_REDELIVER_INTENTjamais rappelé. Pourquoi?
Asif Mushtaq
@IlyaGazman Je suis respectueusement en désaccord. Arrêté et tué sont deux mots très différents. Cette réponse explique correctement le problème de manière simple et directe.
NoHarmDan
23

La documentation pour START_STICKYet START_NOT_STICKYest assez simple.

START_STICKY:

Si le processus de ce service est interrompu lors de son démarrage (après son retour de onStartCommand(Intent, int, int)) , laissez-le à l'état démarré mais ne conservez pas cette intention délivrée. Plus tard, le système essaiera de recréer le service. Parce qu'il est à l'état démarré , il garantira l'appel onStartCommand(Intent, int, int) après la création de la nouvelle instance de service; s'il n'y a pas de commandes de démarrage en attente à livrer au service, il sera appelé avec un objet d'intention nulle, vous devez donc prendre soin de vérifier cela.

Ce mode est logique pour les choses qui seront explicitement démarrées et arrêtées pour s'exécuter pendant des périodes arbitraires, comme un service effectuant une lecture de musique de fond.

Exemple: service local

START_NOT_STICKY:

Si le processus de ce service est interrompu lors de son démarrage (après son retour onStartCommand(Intent, int, int)), et qu'il n'y a pas de nouvelle intention de démarrage à lui fournir, retirez le service de l'état démarré et ne recréez pas avant un futur appel explicite à Context.startService(Intent). Le service ne recevra pas d' onStartCommand(Intent, int, int)appel avec une nullintention car il ne sera pas redémarré s'il n'y a aucune intention en attente à livrer.

Ce mode a du sens pour les choses qui veulent faire du travail après avoir été démarrées, mais qui peuvent être arrêtées sous la pression de la mémoire et qui recommenceront explicitement plus tard pour faire plus de travail. Un exemple d'un tel service serait celui qui interroge les données d'un serveur: il pourrait programmer une alarme pour interroger toutes les Nminutes en faisant démarrer l'alarme par son service. Lorsqu'il onStartCommand(Intent, int, int)est appelé depuis l'alarme, il planifie une nouvelle alarme pendant N minutes plus tard et génère un thread pour effectuer sa mise en réseau. Si son processus est interrompu lors de cette vérification, le service ne sera pas redémarré tant que l'alarme ne se déclenchera pas.

Exemple: ServiceStartArguments.java

Marvin Pinto
la source
pas de chance les gars .. Je n'ai pas pu relier la documentation dans le mot du profane. Je voudrais me rapporter à un scénario en temps réel. Je voudrais montrer un exemple sur l'appareil. afin qu'ils puissent comprendre plus facilement.
prago
pour START_STICKY et START_NOT_STICKY onStartCommand () ne sera exécuté qu'une seule fois et en sortira. Je suis passé par l'exemple que vous avez souligné, mais mon doute est de savoir combien de fois onStartCommand () sera exécuté. si je retire START_STICKY et que j'essaie toujours de recréer le service, le service s'exécute-t-il sur StartCommand alors ??
prago
qu'advient-il de l'activité lorsque le service est recréé? L'activité est-elle également recréée?
ransh
Je suppose que nous ne saurons jamais
Denny