Die Klasse Activity ist eine wichtige Komponente einer Android-App. Die Art und Weise, wie Aktivitäten gestartet und zusammengestellt werden, ist ein grundlegender Bestandteil des Anwendungsmodells der Plattform. Anders als bei Programmierparadigmen, bei denen Apps mit einer main-Methode gestartet werden, initiiert das Android-System Code in einer Activity-Instanz, indem es bestimmte Callback-Methoden aufruft, die bestimmten Phasen ihres Lebenszyklus entsprechen.
In diesem Dokument wird das Konzept von Aktivitäten vorgestellt und es werden einige einfache Anleitungen für die Arbeit mit ihnen gegeben. Weitere Informationen zu Best Practices für die Architektur Ihrer App finden Sie im Leitfaden zur App-Architektur.
Das Konzept von Aktivitäten
Die Nutzererfahrung in einer mobilen App unterscheidet sich von der in der Desktopversion, da die Interaktion eines Nutzers mit der App nicht immer am selben Ort beginnt. Stattdessen beginnt die User Journey oft nicht deterministisch. Wenn Sie beispielsweise eine E‑Mail-App über den Startbildschirm öffnen, sehen Sie möglicherweise eine Liste mit E‑Mails. Wenn Sie hingegen eine Social-Media-App verwenden, die dann Ihre E‑Mail-App startet, gelangen Sie möglicherweise direkt zum Bildschirm der E‑Mail-App, auf dem Sie eine E‑Mail verfassen können.
Die Klasse Activity wurde entwickelt, um dieses Paradigma zu erleichtern. Wenn eine App eine andere aufruft, ruft die aufrufende App eine Aktivität in der anderen App auf und nicht die App als Ganzes. So dient die Aktivität als Ausgangspunkt für die Interaktion einer App mit dem Nutzer. Sie implementieren eine Aktivität als Unterklasse der Klasse Activity.
Eine Aktivität stellt das Fenster bereit, in dem die App ihre Benutzeroberfläche rendert. Dieses Fenster füllt in der Regel den Bildschirm aus, kann aber auch kleiner sein und über anderen Fenstern schweben.
Normalerweise wird eine Aktivität in einer App als Hauptaktivität angegeben. Das ist der erste Bildschirm, der angezeigt wird, wenn der Nutzer die App startet. In modernen Compose-Apps ist dies die einzige Aktivität, die erforderlich ist, da sie Composables in einer Architektur mit nur einer Aktivität hostet und keine eigene Ansichtshierarchie hat. Anstelle mehrerer Aktivitäten für Bildschirme enthält die Host-Aktivität Composables mit mehreren Navigationszielen.
Wenn Sie Aktivitäten in Ihrer App verwenden möchten, müssen Sie Informationen dazu im Manifest der App registrieren. Außerdem ist es empfehlenswert, sich mit den Aktivitätslebenszyklen vertraut zu machen. Im Rest dieses Dokuments werden diese Themen vorgestellt.
Manifest konfigurieren
Damit Ihre App Aktivitäten verwenden kann, müssen Sie die Aktivitäten und bestimmte ihrer Attribute im Manifest deklarieren.
Aktivitäten deklarieren
Öffnen Sie zum Deklarieren Ihrer Aktivität die Manifestdatei und fügen Sie ein <activity>-Element als untergeordnetes Element des <application>-Elements hinzu. Beispiel:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
Das einzige erforderliche Attribut für dieses Element ist android:name, das den Klassennamen der Aktivität angibt. Sie können auch Attribute hinzufügen, die Aktivitätsmerkmale wie Label, Symbol oder UI-Design definieren. Weitere Informationen zu diesen und anderen Attributen finden Sie in der Referenzdokumentation zum <activity>-Element.
Intent-Filter deklarieren
Intent-Filter sind eine sehr leistungsstarke Funktion der Android-Plattform. Sie ermöglichen es, eine Aktivität nicht nur auf Grundlage einer expliziten, sondern auch einer impliziten Anfrage zu starten. Bei einer expliziten Anfrage wird das System beispielsweise angewiesen, „die Aktivität ‚E‑Mail senden‘ in der Gmail App zu starten“. Im Gegensatz dazu wird bei einer impliziten Anfrage das System angewiesen, „einen Bildschirm zum Senden von E‑Mails in einer beliebigen Aktivität zu starten, die die Aufgabe ausführen kann“. Wenn die System-UI einen Nutzer fragt, welche App für die Ausführung einer Aufgabe verwendet werden soll, ist ein Intent-Filter im Einsatz.
Sie können diese Funktion nutzen, indem Sie ein <intent-filter>-Attribut im <activity>-Element deklarieren. Die Definition dieses Elements enthält ein <action>-Element und optional ein <category>-Element und/oder ein <data>-Element. Diese Elemente werden kombiniert, um den Typ der Intention anzugeben, auf die Ihre Aktivität reagieren kann. Das folgende Code-Snippet zeigt beispielsweise, wie eine Aktivität konfiguriert wird, die Textdaten und E-Mails sendet und Anfragen von anderen Aktivitäten empfängt, um dies zu tun:
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="mailto" />
</intent-filter>
</activity>
In diesem Beispiel gibt das Element <action> an, dass bei dieser Aktivität Daten gesendet werden. Wenn Sie das Element <category> als DEFAULT deklarieren, kann die Aktivität Startanfragen empfangen. Das Element <data> gibt den Typ der Daten an, die von dieser Aktivität gesendet werden können. Das folgende Code-Snippet zeigt, wie die oben beschriebene Aktivität aufgerufen wird, um eine E‑Mail zu verfassen:
fun composeEmail(addresses: Array<String>, subject: String) {
val intent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:") // Only email apps handle this.
putExtra(Intent.EXTRA_EMAIL, addresses)
putExtra(Intent.EXTRA_SUBJECT, subject)
}
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
Wenn Ihre App in sich geschlossen sein soll und andere Apps ihre Aktivitäten nicht aktivieren dürfen, benötigen Sie keine weiteren Intent-Filter. Aktivitäten, die Sie anderen Anwendungen nicht zur Verfügung stellen möchten, sollten keine Intent-Filter haben. Sie können sie selbst mit expliziten Intents starten. Weitere Informationen dazu, wie Ihre Aktivitäten auf Intents reagieren können, finden Sie unter Intents und Intent-Filter.
Eingehende Intents verarbeiten
Das folgende Beispiel zeigt ein Muster für die Verwaltung des Aktivitätslebenszyklus beim Verarbeiten mehrerer Intent-Typen: einzelne Textfreigaben, einzelne Bilder und Arrays mit mehreren Bildern. Durch das Weiterleiten dieser verschiedenen Eingaben über eine zentrale handleIntent-Funktion wird sichergestellt, dass sowohl die ACTION_SEND- als auch die ACTION_SEND_MULTIPLE-Aktionen korrekt geparst und an das ViewModel für ein reaktives UI-Update delegiert werden.
class ExampleActivity : ComponentActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleIntent(intent)
setContent {
ComposeApp(viewModel)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleIntent(intent)
}
private fun handleIntent(intent: Intent?) {
when (intent?.action) {
Intent.ACTION_SEND -> {
if ("text/plain" == intent.type) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
viewModel.handleText(it) // Update UI to reflect text being shared
}
} else if (intent.type?.startsWith("image/") == true) {
(intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java))?.let {
viewModel.handleImage(it) // Update UI to reflect image being shared
}
}
}
Intent.ACTION_SEND_MULTIPLE -> {
if (intent.type?.startsWith("image/") == true) {
intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let {
viewModel.handleMultipleImages(it) // Update UI to reflect multiple images being shared
}
} else {
// Handle other types
}
}
else -> {
// Handle other intents
}
}
}
}
Berechtigungen deklarieren
Mit dem <activity>-Tag des Manifests können Sie festlegen, welche Apps eine bestimmte Aktivität starten können. Eine übergeordnete Aktivität kann eine untergeordnete Aktivität nur starten, wenn beide Aktivitäten in ihrem Manifest dieselben Berechtigungen haben. Wenn Sie ein <uses-permission>-Element für eine übergeordnete Aktivität deklarieren, muss jede untergeordnete Aktivität ein entsprechendes <uses-permission>-Element haben.
Wenn Ihre App beispielsweise eine hypothetische App namens „SocialApp“ verwenden möchte, um einen Beitrag in sozialen Medien zu teilen, muss „SocialApp“ selbst die Berechtigung definieren, die eine aufrufende App haben muss:
<manifest>
<activity android:name="...."
android:permission="com.google.socialapp.permission.SHARE_POST"
/>
Damit Ihre App SocialApp aufrufen darf, muss sie mit dem im Manifest von SocialApp festgelegten Berechtigungssatz übereinstimmen:
<manifest>
<uses-permission android:name="com.google.socialapp.permission.SHARE_POST" />
</manifest>
Weitere Informationen zu Berechtigungen und Sicherheit im Allgemeinen finden Sie in der Sicherheits-Checkliste.
Aktivitätslebenszyklus verwalten
Im Laufe ihres Lebenszyklus durchläuft eine Aktivität eine Reihe von Status. Sie verwenden eine Reihe von Callbacks, um Übergänge zwischen Status zu verarbeiten. In den folgenden Abschnitten werden diese Callbacks vorgestellt. In einer Compose-App wird es nicht empfohlen, diese Callbacks direkt zu verwenden. Verwenden Sie stattdessen die Lifecycle API, um Statusänderungen zu beobachten. Weitere Informationen finden Sie unter Lebenszyklus in Compose einbinden.
onCreate
Sie müssen diesen Callback implementieren, der ausgelöst wird, wenn das System Ihre Aktivität erstellt. Bei der Implementierung sollten die wesentlichen Komponenten Ihrer Aktivität initialisiert werden. Ihre App sollte hier beispielsweise Ansichten erstellen und Daten an Listen binden.
In einer Compose-App können Sie diesen Callback verwenden, um das Host-Composable mit setContent einzurichten, wie unten gezeigt:
class MyActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Text(text = stringResource(id = R.string.greeting))
}
}
}
Wenn onCreate abgeschlossen ist, ist der nächste Callback immer onStart.
onStart
Wenn onCreate beendet wird, wechselt die Aktivität in den Status „Gestartet“ und wird für den Nutzer sichtbar. Dieser Callback enthält die letzten Vorbereitungen der Aktivität, bevor sie in den Vordergrund gerückt und interaktiv wird.
onResume
Das System ruft diesen Callback kurz bevor die Aktivität mit dem Nutzer interagiert auf. An diesem Punkt befindet sich die Aktivität oben im Aktivitätsstapel und erfasst alle Nutzereingaben. Die meisten Hauptfunktionen einer App werden in der Methode onResume implementiert.
Der onPause-Callback folgt immer auf onResume.
onPause
Das System ruft onPause auf, wenn die Aktivität den Fokus verliert und in den pausierten Zustand wechselt. Dieser Status tritt beispielsweise auf, wenn der Nutzer auf die Schaltfläche „Zurück“ oder „Letzte Apps“ tippt. Wenn das System onPause für Ihre Aktivität aufruft, bedeutet das technisch gesehen, dass Ihre Aktivität noch teilweise sichtbar ist. Meistens ist es jedoch ein Hinweis darauf, dass der Nutzer die Aktivität verlässt und die Aktivität bald den Status „Beendet“ oder „Fortgesetzt“ erreicht.
Bei einer Aktivität im Status „Pausiert“ kann die Benutzeroberfläche weiterhin aktualisiert werden, wenn der Nutzer dies erwartet. Beispiele für solche Aktivitäten sind ein Navigationskartenausschnitt oder ein Mediaplayer, der gerade wiedergegeben wird. Auch wenn solche Aktivitäten in den Hintergrund treten, erwartet der Nutzer, dass die Benutzeroberfläche weiterhin aktualisiert wird.
Sie sollten nicht onPause verwenden, um Anwendungs- oder Nutzerdaten zu speichern, Netzwerkaufrufe zu tätigen oder Datenbanktransaktionen auszuführen. Informationen zum Speichern von Daten finden Sie unter Vorübergehenden UI-Status speichern und wiederherstellen.
Sobald onPause ausgeführt wurde, ist der nächste Callback entweder onStop oder onResume, je nachdem, was passiert, nachdem die Aktivität in den Status „Pausiert“ wechselt.
onStop
Das System ruft onStop auf, wenn die Aktivität für den Nutzer nicht mehr sichtbar ist. Das kann passieren, wenn die Aktivität beendet wird, eine neue Aktivität gestartet wird oder eine vorhandene Aktivität in den Status „Resumed“ wechselt und die beendete Aktivität abdeckt. In all diesen Fällen ist die beendete Aktivität nicht mehr sichtbar.
Der nächste Callback, den das System aufruft, ist entweder onRestart, wenn die Aktivität zurückkehrt, um mit dem Nutzer zu interagieren, oder onDestroy, wenn diese Aktivität vollständig beendet wird.
onRestart
Das System ruft diesen Callback auf, wenn eine Aktivität im Status „Beendet“ neu gestartet wird. Mit onRestart wird der Status der Aktivität ab dem Zeitpunkt wiederhergestellt, zu dem sie beendet wurde.
Auf diesen Callback folgt immer onStart.
onDestroy
Das System ruft diesen Callback auf, bevor eine Aktivität zerstört wird.
Dieser Callback ist der letzte, den die Aktivität empfängt. onDestroy wird in der Regel implementiert, um sicherzustellen, dass alle Ressourcen einer Aktivität freigegeben werden, wenn die Aktivität oder der Prozess, der sie enthält, beendet wird.
Dieser Abschnitt bietet nur eine Einführung in dieses Thema. Eine detailliertere Beschreibung des Aktivitätslebenszyklus und seiner Callbacks finden Sie unter Der Aktivitätslebenszyklus.