Was passiert, wenn ein Android-Dienst mehrmals gestartet wird?

119

Wenn ich folgenden Code habe:

Intent intent = new Intent(this,DownloadService.class);     
for(int i=0;i<filesArray.length;i++){        
     startService(intent);          
}

In diesem Code DownloadServiceerweitert IntentService.

Wenn ich jetzt anrufe startService(intent), bedeutet dies, dass ich jedes Mal einen neuen Dienst starte, wenn er startService(intent)aufgerufen wird, oder bedeutet dies, dass er DownloadServiceeinmal ausgeführt wird und jedes Mal, wenn ich startService(intent)ihn anrufe, eine andere Absicht mit einer anderen Start-ID übergeben wird.

Ist das sinnvoll und welches davon ist der Fall?

Bytekeks
quelle

Antworten:

166

Der Dienst wird nur in einer Instanz ausgeführt. Jedes Mal, wenn Sie den Dienst starten, wird die onStartCommand()Methode aufgerufen.

Dies ist hier dokumentiert

Philipp Wendt
quelle
1
Vielen Dank. Dort heißt es auch: "Die startService () -Methode kehrt sofort zurück und das Android-System ruft die onStartCommand () -Methode des Dienstes auf. Wenn der Dienst noch nicht ausgeführt wird, ruft das System zuerst onCreate () und dann onStartCommand () auf." Wenn der Dienst bereits ausgeführt wird, überspringt das System die onCreate () -Methode und ruft nur onStartCommand () auf, oder was?
Bytebiscuit
Ich weiß es nicht wirklich, aber ich bin mir ziemlich sicher, dass dies der Fall ist (es ist sehr sinnvoll, nicht anzurufen, onCreate()wenn der Dienst bereits erstellt wurde). Es sollte leicht zu bestimmen sein, ob Sie Log.i()in beide Rückrufe ein eingeben und das LogCat überprüfen.
Philipp Wendt
Hab das einfach gemacht ... und seltsamerweise startet es das onCreate nach dem letzten Aufruf von startService () !!!
Bytebiscuit
15
Das liegt daran, dass startService()es asynchron ist. Während Sie die Anrufe schleifen, hat der Dienst selbst keine Ressourcen erhalten und wurde noch nicht gestartet.
Philipp Wendt
1
@neelabh nicht "sofort", es dauert einige Zeit, bis der Dienst gestartet wird, und die "for" -Schleife wird immer noch ausgeführt und ruft den Dienst immer wieder auf, sodass bei den ersten Versuchen noch kein Dienst ausgeführt wird ... Daher wird die Methode startService () einige Male aufgerufen, bis der Dienststart abgeschlossen ist. Bitte entschuldigen Sie mein schlechtes Englisch.
Mzalazar
21

Absolut korrekt. Für einen Bewerbungsprozess wird nur eine Service-Instanz erstellt. Und wenn Sie StartService();erneut aufrufen , wird nur onStartCommand()aufgerufen und eine neue Absicht an die onStartCommand()Methode übergeben.

Hinweis: onCreate() wird nicht erneut aufgerufen.

bindService()Mehrfaches Anrufen :

Wenn Sie bindService()mehrmals aufrufen , wird erneut nur eine Instanz für den Dienst verwendet, und Android Runtime gibt dasselbe IBinder-Objekt an den Client zurück.

Bedeutet, onBind()wird nicht mehrfach aufgerufen. Und nur das zwischengespeicherte IBinder-Objekt wird zurückgegeben.

Anish Mittal
quelle
Muss onStop()für jeden Korrespondenten aufgerufen werden onStartCommand?
IgorGanapolsky
6
@IgorGanapolsky: Erstens gibt es keine solche Rückrufmethode onStop () in Service. Wir müssen stopService () oder stopSelf () aufrufen, um einen Dienst zu stoppen. Und wenn onStartCommand () aus mehreren Gründen mehrmals aufgerufen wurde, müssen wir nur einmal stopSelf () oder stopService () aufrufen. Wenn Sie IntentService verwenden, sollten Sie stopSelfResult (int id) aufrufen und die Start-ID der Anforderung von onHandleIntent () übergeben, wodurch die entsprechende Start-ID-Anforderung gestoppt wird, die in die Arbeitswarteschlange von IntentService gestellt wurde. Hoffe das hilft.
Anish Mittal
8

Das Hinzufügen weiterer Informationen zu den obigen Antworten, die für andere hilfreich sein können, besteht darin, startIddass die onStartCommand()empfangene Methode für jeden startService()Aufruf anders ist .

Auch wenn wir wie oben erwähnt in eine for-Schleife schreiben, wird der eingeschriebene Code onHandleIntent()so oft ausgeführt, wie durch die Frequenz der for-Schleife definiert, jedoch nacheinander und nicht parallel.

Das Konzept besteht darin, IntentServiceeine Arbeitswarteschlange und jede startService()auszulösende Anforderung zu erstellen, onStartCommand()die wiederum die Absicht in der Arbeitswarteschlange speichert und die Absicht dann einzeln an weiterleitet onHandleIntent().

Rahul Gupta
quelle
2

Laut dem Dokument :

Die startService () -Methode wird sofort zurückgegeben, und das Android-System ruft die onStartCommand () -Methode des Dienstes auf. Wenn der Dienst noch nicht ausgeführt wird, ruft das System zuerst onCreate () und dann onStartCommand () auf.

und

Mehrere Anforderungen zum Starten des Dienstes führen zu mehreren entsprechenden Aufrufen des onStartCommand () des Dienstes. Es ist jedoch nur eine Anforderung zum Beenden des Dienstes (mit stopSelf () oder stopService ()) erforderlich, um ihn zu stoppen.

Amir Rezazadeh
quelle