START_STICKY und START_NOT_STICKY

Antworten:

371

Beide Codes sind nur relevant, wenn dem Telefon der Speicher ausgeht und der Dienst beendet wird, bevor die Ausführung abgeschlossen ist. START_STICKYWeist das Betriebssystem an, den Dienst neu zu erstellen, nachdem er über genügend Speicher verfügt, und ihn onStartCommand()erneut mit einer Null-Absicht aufzurufen . START_NOT_STICKYWeist das Betriebssystem an, den Dienst nicht erneut zu erstellen. Es gibt auch einen dritten Code START_REDELIVER_INTENT, der das Betriebssystem anweist, den Dienst neu zu erstellen und die gleiche Absicht erneut zu liefern onStartCommand().

Dieser Artikel von Dianne Hackborn erklärte den Hintergrund viel besser als die offizielle Dokumentation.

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

Der Schlüsselteil hier ist ein neuer Ergebniscode, der von der Funktion zurückgegeben wird und dem System mitteilt, was es mit dem Dienst tun soll, wenn sein Prozess während der Ausführung beendet wird:

START_STICKY entspricht im Wesentlichen dem vorherigen Verhalten, bei dem der Dienst "gestartet" bleibt und später vom System neu gestartet wird. Der einzige Unterschied zu früheren Versionen der Plattform besteht darin, dass onStartCommand () bei einem Neustart aufgrund eines gestoppten Prozesses bei der nächsten Instanz des Dienstes mit einer Null-Absicht aufgerufen wird, anstatt überhaupt nicht aufgerufen zu werden. Dienste, die diesen Modus verwenden, sollten immer nach diesem Fall suchen und angemessen damit umgehen.

START_NOT_STICKY gibt an, dass nach der Rückkehr von onStartCreated () der Dienst gestoppt und nicht neu gestartet wird, wenn der Prozess ohne verbleibende Startbefehle beendet wird. Dies ist viel sinnvoller für Dienste, die nur ausgeführt werden sollen, während an sie gesendete Befehle ausgeführt werden. Beispielsweise kann ein Dienst alle 15 Minuten von einem Alarm aus gestartet werden, um einen Netzwerkstatus abzufragen. Wenn es während dieser Arbeit getötet wird, ist es am besten, es einfach anzuhalten und beim nächsten Alarm auszulösen.

START_REDELIVER_INTENT ist wie START_NOT_STICKY, außer wenn der Prozess des Dienstes abgebrochen wird, bevor stopSelf () für eine bestimmte Absicht aufgerufen wird, wird diese Absicht erneut an ihn gesendet, bis er abgeschlossen ist (es sei denn, nach einigen weiteren Versuchen kann er immer noch nicht abgeschlossen werden). an welchem ​​Punkt das System aufgibt). Dies ist nützlich für Dienste, die Arbeitsbefehle erhalten und sicherstellen möchten, dass sie die Arbeit für jeden gesendeten Befehl schließlich abschließen.

Frank Leigh
quelle
1
So vermeiden Sie doppelte Aufrufe von task handleStart (intent, startId); wie werden sowohl onStart () als auch onStartCommand aufgerufen? ist es ein gutes Design? @ Frank Leigh
Sazzad Hissain Khan
2
Was ist das Standardflag, wenn keines angegeben ist?
IgorGanapolsky
3
Wenn Sie dem "return super.onStartCommand (...);" folgen Sie werden sehen, dass für den Fall, dass Ihre SDK-Zielversion standardmäßig kleiner als ECLAIR (API5 = 2.0) ist, START_STICKY_COMPATIBILITY zurückgegeben wird und ab 2.0 START_STICKY zurückgegeben wird.
MikeL
1
Was meinst du mit "ohne verbleibende Startbefehle" in START_NOT_STICKY?
Malwinder Singh
3
@FrankLeigh Ich stimme nicht zu, dass das so START_REDELIVER_INTENTist START_NOT_STICKY. Stattdessen ist es wieSTART_STICKY
CopsOnRoad
107

KISS Antwort

Unterschied:

START_STICKY

Das System versucht, Ihren Dienst neu zu erstellen, nachdem er beendet wurde

START_NOT_STICKY

Das System versucht nicht , Ihren Dienst neu zu erstellen, nachdem er beendet wurde


Standardbeispiel:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}
Oded Breiner
quelle
5
Das ist eigentlich nicht richtig und verwirrend. Es ist ein Fehler zu sagen: "Dienst wird beendet", weil man denken kann, dass Sie sich auf stopSelf oder stopService beziehen, während Sie sich offensichtlich auf den getöteten Prozess beziehen. Verwenden Sie also besser das Textverfahren in Ihrer Antwort.
Ilya Gazman
Hallo wie ich testen kann START_REDELIVER_INTENT. Ich habe gerade START_STICKYdie App mit den neuesten Apps getestet und beendet. Dann ruft es den Service zurück. Aber START_REDELIVER_INTENTnie wieder angerufen. Warum?
Asif Mushtaq
@IlyaGazman Ich bin respektvoll anderer Meinung. Angehalten und getötet sind zwei sehr unterschiedliche Wörter. Diese Antwort erklärt das Problem auf einfache und unkomplizierte Weise richtig.
NoHarmDan
23

Die Dokumentation für START_STICKYund START_NOT_STICKYist recht unkompliziert.

START_STICKY:

Wenn der Prozess dieses Dienstes beim Starten abgebrochen wird (nachdem Sie von zurückgekehrt sind onStartCommand(Intent, int, int)), lassen Sie ihn im gestarteten Zustand, behalten Sie diese übermittelte Absicht jedoch nicht bei. Später versucht das System, den Dienst neu zu erstellen, da er sich im gestarteten Zustand befindet Es wird garantiert, dass onStartCommand(Intent, int, int) nach dem Erstellen der neuen Dienstinstanz ein Aufruf ausgeführt wird . Wenn keine ausstehenden Startbefehle an den Dienst übermittelt werden sollen, wird der Aufruf mit einem Null-Intent-Objekt ausgeführt. Sie müssen daher darauf achten, dies zu überprüfen.

Dieser Modus ist sinnvoll für Dinge, die explizit gestartet und gestoppt werden, um für beliebige Zeiträume ausgeführt zu werden, z. B. ein Dienst, der die Wiedergabe von Hintergrundmusik durchführt.

Beispiel: Beispiel für einen lokalen Dienst

START_NOT_STICKY:

Wenn der Prozess dieses Dienstes beim onStartCommand(Intent, int, int))Starten abgebrochen wird (nachdem Sie von zurückgekehrt sind und keine neuen Startabsichten für die Übermittlung an diesen Dienst vorhanden sind, nehmen Sie den Dienst aus dem gestarteten Zustand und erstellen Sie ihn erst nach einem zukünftigen expliziten Aufruf von Context.startService(Intent). Der Dienst erhält keinen onStartCommand(Intent, int, int)Anruf mit einer nullAbsicht, da er nicht neu gestartet wird, wenn keine ausstehenden Absichten zu liefern sind.

Dieser Modus ist sinnvoll für Dinge, die aufgrund des Startvorgangs etwas arbeiten möchten, kann jedoch unter Speicherdruck gestoppt werden und startet sich später explizit erneut, um mehr Arbeit zu erledigen. Ein Beispiel für einen solchen Dienst wäre ein Dienst, der Daten von einem Server abfragt: Er könnte einen Alarm so planen, dass er jede NMinute abfragt, indem der Alarm seinen Dienst startet. Wenn onStartCommand(Intent, int, int)es vom Alarm aufgerufen wird, plant es einen neuen Alarm für N Minuten später und erzeugt einen Thread, um seine Vernetzung durchzuführen. Wenn der Prozess während dieser Überprüfung abgebrochen wird, wird der Dienst erst neu gestartet, wenn der Alarm ausgelöst wird.

Beispiel: ServiceStartArguments.java

Marvin Pinto
quelle
Kein Glück, Leute. Ich konnte die Dokumentation nicht mit Laienwörtern in Verbindung bringen. Ich möchte mich auf ein Echtzeitszenario beziehen. Ich möchte ein Beispiel auf dem Gerät zeigen. damit sie leichter verstehen können.
Prago
für START_STICKY und START_NOT_STICKY wird onStartCommand () nur einmal ausgeführt und verlässt es. Ich habe das Beispiel durchgesehen, auf das Sie hingewiesen haben, aber ich bezweifle, wie oft onStartCommand () ausgeführt wird. Wenn ich START_STICKY erneut ausführe und trotzdem versuche, den Dienst neu zu erstellen, wird der Dienst dann auf Startbefehl ausgeführt?
Prago
Was passiert mit der Aktivität, wenn der Dienst neu erstellt wird? Wird die Aktivität auch neu erstellt?
Ransh
Ich denke, wir werden es nie erfahren
Denny