17 Intents und Services

17.1 Intents

Ein Intent in Android ist eine Art Nachricht oder Anforderung, die Sie verwenden können, um eine andere Komponente in Ihrem System (wie eine andere Activity, einen Service oder einen Broadcast Receiver) aufzurufen oder zu starten. Es gibt zwei Hauptarten von Intents:

val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
val intent = Intent(applicationContext, MainActivity::class.java)
startActivity(intent)
val url = "https://www.google.com"
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(intent)

17.2 Services

Ein Service in Android ist eine Komponente, die im Hintergrund lange laufende Operationen ausführt, ohne eine Benutzeroberfläche zu haben. Services können zum Beispiel zum Abspielen von Musik, zum Herunterladen von Dateien oder zum regelmäßigen Abrufen von Daten aus dem Internet verwendet werden.

Es gibt zwei Hauptarten von Services:

Es ist wichtig zu beachten, dass Services im Hintergrund laufen und daher nicht mit der Benutzeroberfläche der Anwendung interagieren können. Außerdem haben sie, obwohl sie im Hintergrund laufen, Auswirkungen auf die Leistung und den Akkuverbrauch des Geräts, daher sollte ihre Verwendung sorgfältig geplant und optimiert werden.

In Android können Sie Intents und Services verwenden, um Aufgaben auszuführen.

Hier ist ein einfacher Service:

class MyService : Service() {
    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        // Ihr Code hier...
        return super.onStartCommand(intent, flags, startId)
    }
}

Um einen Service zu starten, können Sie einen Intent verwenden:

val intent = Intent(this, MyService::class.java)
startService(intent)

Um einen Service zu stoppen, verwenden Sie auch einen Intent:

val intent = Intent(this, MyService::class.java)
stopService(intent)

17.3 Service Class und IntentService Class

Service Class

Ein Service in Android ist eine Komponente, die im Hintergrund lange laufende Operationen ausführt, ohne eine Benutzeroberfläche bereitzustellen. Einige Anwendungsfälle beinhalten das Herunterladen von Dateien, das Abspielen von Musik, oder das Durchführen von Netzwerkanfragen.

Services laufen auf dem Haupt-Thread der Anwendung, daher sollte jeder rechenintensive oder blockierende Code in einem separaten Thread ausgeführt werden, um das Einfrieren der Benutzeroberfläche zu vermeiden.

Hier sind einige wichtige Punkte zu Services:

. Gestartete Services werden durch die Methode startService() gestartet und laufen unabhängig von der Komponente, die sie gestartet hat. Gebundene Services werden durch die Methode bindService() gebunden und können mit der Komponente interagieren, die sie gebunden hat.

IntentService Class

IntentService ist eine Unterklasse von Service und wurde entwickelt, um Arbeiten in einem Worker-Thread zu erleichtern. Jede Intent-Anforderung führt zu einem Arbeitsschritt, und die Arbeitsschritte werden nacheinander abgearbeitet – es werden also keine gleichzeitigen Operationen durchgeführt. Nachdem alle Anfragen abgearbeitet sind, wird der IntentService automatisch gestoppt.

Hier sind einige wichtige Punkte zu IntentServices:

Zusammenfassend lässt sich sagen, dass die Wahl zwischen Service und IntentService von den spezifischen Anforderungen Ihrer Anwendung abhängt. Wenn Sie eine einzelne, lange andauernde Operation haben, könnte ein Service die richtige Wahl sein. Wenn Sie jedoch mehrere Aufgaben haben, die nacheinander abgearbeitet werden müssen und Sie sich nicht um Threading kümmern möchten, könnte ein IntentService besser geeignet sein.

Service Class

Eine Service-Klasse könnte so aussehen:

class MyService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Auf diesem Thread sollte keine zeitaufwändige Operation durchgeführt werden
        // stattdessen können Sie einen separaten Thread starten
        return START_STICKY
    }

    override fun onBind(intent: Intent): IBinder? {
        // return the Communication channel to the service.
        return null
    }
}

Um diesen Service zu starten, können Sie in Ihrer Activity folgenden Code verwenden:

val intent = Intent(this, MyService::class.java)
startService(intent)

IntentService Class

Ein IntentService könnte so aussehen:

class MyIntentService : IntentService("MyIntentService") {
    override fun onHandleIntent(intent: Intent?) {
        // Dieser Code wird in einem separaten Thread ausgeführt.
        // Hier können Sie zeitaufwändige Operationen durchführen.
    }
}

Um diesen IntentService zu starten, können Sie in Ihrer Activity folgenden Code verwenden:

val intent = Intent(this, MyIntentService::class.java)
startService(intent)

Bitte beachten Sie, dass ab Android 8.0 (API Level 26) aufgrund der Hintergrundausführungslimits Services im Hintergrund nicht mehr gestartet werden können. Sie müssen stattdessen startForegroundService() verwenden und den Service innerhalb von fünf Sekunden in den Vordergrund stellen. Alternativ können Sie auch WorkManager für Aufgaben verwenden, die eine garantierte Ausführung erfordern.

17.4 Manifest

Alle Services (einschließlich IntentServices) müssen in der Manifest-Datei Ihrer App deklariert werden. Sie tun dies, indem Sie einen <service>-Eintrag innerhalb des <application>-Tags der Manifest-Datei hinzufügen. Hier ist ein Beispiel, wie Sie das tun können:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApp" >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Service declaration -->
        <service android:name=".MyService" />
        <service android:name=".MyIntentService" />
    </application>

</manifest>

In diesem Beispiel wurden sowohl MyService

als auch MyIntentService in der Manifest-Datei deklariert. Beachten Sie, dass der android:name-Attributwert der vollqualifizierte Name der Service-Klasse ist.

Die Deklaration von Services in der Manifest-Datei ermöglicht es dem Android-System, diese Services zu erkennen und richtig zu verwalten. Wenn Sie einen Service nicht im Manifest deklarieren, wird das System den Service nicht ausführen können, und wenn Sie versuchen, den Service zu starten, wird eine ActivityNotFoundException ausgelöst.

17.5 JobIntentService

Mit der Einführung von Android Oreo (API 26) wurde IntentService als veraltet markiert und wird seitdem nicht mehr empfohlen. Stattdessen wird empfohlen, JobIntentService zu verwenden, besonders wenn Ihre Anwendung im Hintergrund lange laufende Operationen ausführen muss.

Im Vergleich zu IntentService bietet JobIntentService zusätzliche Vorteile. Er stellt sicher, dass die Operationen im Hintergrund auf Android Oreo und höher korrekt ausgeführt werden, indem er die neuen Hintergrundausführungslimits berücksichtigt.

Hier ist ein Beispiel, wie Sie einen JobIntentService verwenden können:

class MyJobIntentService : JobIntentService() {

    companion object {
        const val JOB_ID = 1000

        fun enqueueWork(context: Context, work: Intent) {
            enqueueWork(context, MyJobIntentService::class.java, JOB_ID, work)
        }
    }

    override fun onHandleWork(intent: Intent) {
        // Hier führen Sie Ihre Hintergrundaufgabe aus
    }
}

Um diesen JobIntentService zu starten, können Sie in Ihrer Aktivität oder einer anderen Komponente folgenden Code verwenden:

val serviceIntent = Intent(this, MyJobIntentService::class.java)
MyJobIntentService.enqueueWork(this, serviceIntent)

Und wie bei anderen Services müssen Sie auch JobIntentService in Ihrer AndroidManifest.xml-Datei deklarieren:

<service
    android:name=".MyJobIntentService"
    android:permission="android.permission.BIND_JOB_SERVICE">
</service>

Bitte beachten Sie, dass Sie ab Android 8.0 (API Level 26) die Berechtigung BIND_JOB_SERVICE benötigen, um JobIntentService verwenden zu können. Außerdem kann die Ausführung von Jobs durch das Betriebssystem verzögert werden, um die Batterielebensdauer zu optimieren, insbesondere wenn die App derzeit nicht im Vordergrund läuft.

17.6 Services stoppen

In Android kann ein Service entweder sich selbst stoppen, oder er kann von einer externen Komponente, wie einer Aktivität, gestoppt werden.

17.6.1 Ein Service stoppt sich selbst

Ein Service kann sich selbst stoppen, indem er die Methode stopSelf() aufruft. Diese Methode ist nützlich, wenn der Service seine Arbeit abgeschlossen hat und nicht länger benötigt wird. Hier ist ein Beispiel:

class MyService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Führe einige Operationen aus...

        // Nach Abschluss der Operationen stoppen wir den Service
        stopSelf()

        return START_NOT_STICKY
    }

    override fun onBind(intent: Intent): IBinder? {
        // Rückgabe des Kommunikationskanals zum Dienst.
        return null
    }
}

In diesem Beispiel führt der Service einige Operationen aus, wenn er gestartet wird. Nachdem diese Operationen abgeschlossen sind, ruft der Service stopSelf(), um sich selbst zu stoppen.

17.6.2 Ein Service wird von einer externen Komponente gestoppt

Eine externe Komponente, wie eine Aktivität, kann einen Service stoppen, indem sie die Methode stopService() aufruft. Hier ist ein Beispiel:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun stopMyService(view: View) {
        val intent = Intent(this, MyService::class.java)
        stopService(intent)
    }
}

In diesem Beispiel gibt es eine Methode stopMyService(), die aufgerufen wird, wenn ein bestimmter Button in der Aktivität geklickt wird. Wenn dieser Button geklickt wird, erstellt die Methode einen Intent, der den Service identifiziert, und ruft stopService() mit diesem Intent auf, um den Service

zu stoppen.

Bitte beachten Sie, dass die Methode stopService() den Service sofort stoppt, unabhängig davon, ob er noch Arbeit zu erledigen hat oder nicht. Wenn Sie einen Service haben, der eine wichtige oder zeitaufwändige Aufgabe ausführt, sollten Sie sicherstellen, dass diese Aufgabe korrekt beendet wird, bevor der Service gestoppt wird. Dies könnte bedeuten, dass Sie eine Logik in Ihrer Serviceklasse implementieren, um die laufenden Aufgaben sicher abzubrechen, wenn stopSelf() oder stopService() aufgerufen wird.