Alles zu Services unter Android

Android Entwicklung: Grundlagen Logo
Was ist ein Service?

Ein „Android Service“ ist eine App-Komponente, die im Hintergrund ausgeführt wird, um permanent eine bestimmte Operation durchzuführen. Eine solche Operation kann z.B. das Abspielen von Musik oder das Aufzeichnen von Bewegung durch einen GPS-Tracker sein. Der Benutzer muss dabei mit Services niemals interagieren.

Ein Service wird durch eine andere Komponente (z.B. Activity) gestartet und bleibt selbst dann noch im Hintergrund aktiv, wenn der Benutzer z.B. zu einer anderen App wechselt oder die App, in der der Service gestartet wurde, zerstört ist. Außerdem muss jeder Service in die „AndroidManifest.xml„-Datei eingetragen werden.

 

Welche Service-Arten gibt es?

Grundsätzlich gibt es zwei Arten von Services:

Started/Unbound Service

Ein Unbound-Service ist ein Service, den eine andere App-Komponente (z.B. Activity) durch den Aufruf von "startService()" startet, was wiederum zu einem Aufruf der Methode "onStartCommand()" des Services führt. Ein solcher Service hat einen eigenen Lebenszyklus, der völlig unabhängig vom Lebenszyklus derjenigen Komponente ist, die diesen gestartet hat. Der Unbound-Service kann auf zwei unterschiedliche Weisen beendet werden: Entweder beendet der Service sich nach Erledigung seiner Aufgabe durch den Aufruf der Methode "stopSelf()" selbst oder er wird durch eine andere Komponente mittels der "stopService()"-Methode beendet.

 

Bound Service

Ein Bound-Service ist ein Service, der es App-Komponenten (z.B. Activity, Content Provider) erlaubt, diesen an sich zu binden, indem die "bindService()"-Methode aufgerufen wird. Dabei sind sowohl Komponenten der eigenen App, als auch Komponenten anderer Apps gemeint. Ein solcher Service muss am Ende über die Methode "onUnbind()" explizit wieder gelöst werden. Dabei besteht die Möglichkeit, dass sich mehrere Komponenten im selben Prozess gleichzeitig mit einem Bound-Service verbinden können.

 

Welchen Lebenszyklus haben Services?
Ein Service verfügt, genau wie eine Activity, über einen eigenen Lebenszyklus mit verschiedenen Callback-Methoden. Wenn du möchtest, kannst du diese Methoden implementieren, um Zustands-Änderungen eines Service zu überwachen. Nachfolgend zeigen wir dir zwei Schaubilder für den Lebenszyklus eines "Unbound-" und "Bound-Services". Jeweils direkt unterhalb eines Schaubildes beschreiben wir kurz die unterschiedlichen Methoden (haben Buchstaben) und Zustände (haben Nummern).

 

Lebenszyklus für einen Unbound Service:

Lebenszyklus: Unbound Service

 

a) Methode: onCreate()
Android ruft diese Callback-Methode auf, wenn der Service erstmalig erstellt wird. Die Methode führt dabei initiale und einmalige Setup-Prozeduren durch. Sofern der Service bereits läuft, wird diese Methode natürlich nicht aufgerufen. Die Methode darf zudem nicht direkt aufgerufen werden, sondern nur über die "startService()"-Methode.

Service: onCreate()-Methode

 

(1) Zustand: Created
Nachdem die Methode "onCreate()" aufgerufen wurde, ist der Service im Zustand "Created".

 

b) Methode: onStartCommand()
Das System ruft diese Methode immer dann auf, wenn eine andere Komponente, wie z.B. eine Activity, durch den Aufruf von "startService()" das Starten des Services anfordert. Falls du die "onStartCommand()"-Methode implementierst, musst du den Service durch die Methode "stopService()" auch wieder stoppen, sobald dieser seine Arbeit beendet hat. Auch hier gilt wieder, die Methode nicht direkt, sondern über "startService()" aufzurufen!

Service: onStartCommand()-Methode
Der Methode werden drei Parameter übergeben:

intent: Der Intent, der von der anfordernden Komponente über "startService()" mitgegeben wurde.

flags: Flags sind zusätzliche Informationen, die zur Startaufforderung mitgegeben werden. Sie sind wichtig, falls der Prozess, indem sich der Service befindet, plötzlich durch Speichernot beendet wird. Wenn dieser Fall eintritt, muss Android nämlich wissen, was dann passieren soll. Dabei kann Android über die folgenden Flags mitgeteilt werden, was es tun soll:

a) START_REDELIVER_INTENT: Hier startet Android den Prozess neu, sobald wieder genug Speicher da ist und es erfolgt ein Aufruf der "onStartCommand()"-Methode mit dem letzten Intent-Objekt als Parameter.

b) START_STICKY: Hier startet Android ebenfalls den Prozess neu, sobald wieder genug Speicher da ist und es erfolgt ein Aufruf der "onStartCommand()"-Methode mit Null als Parameter für den Intent.

c) START_NOT_STICKY: Hier startet Android den Prozess nicht neu.

startId: Dieser Parameter dient zur eindeutigen Identifizierung des Services. Sofern ein Service etwa über die Methode "stopSelfResult()" zerstört werden soll, wird diese ID benötigt.

 

(2) Zustand: Running
Nach den Aufrufen von "startService()" und "onStartCommand()" befindet sich ein Service im Zustand "Running" und verarbeitet eine Operation, wie z.B. das Abspielen von Musik im Hintergrund.

 

c) Methode: stopSelf() oder stopService()
Für das Beenden eines Services gibt es zwei unterschiedliche Methoden, die folgendermaßen unterschieden werden:

-> stopSelf():  Diese Methode verwendet ein Service, um sich nach der Durchführung einer Operation selbst zu beenden.

-> stopService(): Diese Methode wird von einer anderen Komponente, wie z.B. einer Activity verwendet, um einen Service zu beenden.

Service: stopService()-Methode

 

(3) Zustand: Stopped
Nachdem der Service durch eine der beiden Methoden "stopSelf()" oder "stopService()" beendet wurde, befindet sich der Service im Zustand "Stopped".

 

d) Methode: onDestroy()
Android ruft diese Methode auf, um dem Service mitzuteilen, dass dieser überflüssig geworden ist und nun zerstört wird. Der Service sorgt dann in einem solchen Fall dafür, dass alle Ressourcen (z.B. Threads) wieder freigegeben werden.

Service: onDestroy()-Methode

 

(4) Zustand: Shut down
Nachdem die Methode "onDestroy()" aufgerufen wurde, ist der Service nicht länger am Leben und alle von ihm belegten Ressourcen sind wieder freigegeben.

 

Lebenszyklus für einen Bound Service:

Lebenszyklus: Bound Service

 

Info: Die Methoden "onCreate()" und "onDestroy()" sowie die Zustände "Created" und "Shut Down" sind zwischen "Unbound Services" und "Bound Services" exakt gleich und aus diesem Grund verzichten wir hier auf eine erneute Beschreibung. Falls du etwas zu diesen Methoden bzw. Zuständen wissen möchtest, musst du einfach nur ein Stückchen hochscrollen. Wir starten diesmal die Erklärungen bei der Methode "onBind()" und beenden diese mit dem Zustand "Unbounded".

 

b) Methode: onBind()
Android ruft diese Methode auf, wenn eine andere Komponente sich mit dem Service durch den Aufruf von "bindService()" verbinden will. Wenn du die Methode "onBind()" implementierst, musst du eine Schnittstelle zur Verfügung stellen, so dass die Komponenten mit dem Service kommunizieren können. Das geschieht durch die Rückgabe eines "IBinder"-Objekts. Falls du keine Verbindung herstellen möchtest, dann gibst du schlicht "Null" zurück.

Service: onBind()-Methode

 

(2) Zustand: Bounded
Sobald die Methode "onBind()" aufgerufen wurde, befindet sich ein Service im Zustand "Bounded", d.h. dass eine Komponente nun an diesen Service gebunden ist.

 

c) Methode: onUnbind()
Diese Methode wird von Android aufgerufen, wenn sich Komponenten (z.B. Activities) von einer bestimmten, vom Service veröffentlichten Schnittstelle getrennt haben. Dabei lösen sich die Komponenten konkret über die Methode "unbindService()" vom Service. Der Übergabeparameter der "onUnbind()"-Methode ist der "Intent", der verwendet wurde, um sich an diesen Service zu binden. Der Rückgabewert der Methode "onUnbind()" ist ein Boolean-Wert. Sofern hier "true" zurückgegeben wird, bedeutet das, dass die "onRebind()"-Methode des Services später aufgerufen wird, d.h. sobald sich neue Komponenten mit dem Service verbinden möchten. Bei der Standardimplementierung passiert dagegen nichts und es wird "false" zurückgegeben.

Service: onUnbind()-Methode

 

(3) Zustand: Unbounded
Sobald sich alle Komponenten über die Methode "onUnbind()" von einem Service gelöst haben, befindet sich dieser im Zustand "Unbounded".