Dieses Codelab ist Teil des Android Kotlin Fundamentals-Kurss. Sie profitieren von diesem Kurs, wenn Sie nacheinander die Codelabs durcharbeiten. Alle Kurs-Codelabs finden Sie auf der Landingpage für Kotlin-Grundlagen für Android-Entwickler.
Einführung
In diesem Codelab lernst du einen grundlegenden Teil von Android kennen: den Aktivitäts- und Fragmentlebenszyklus. Der Aktivitätslebenszyklus ist die Gruppe von Status, in denen sich eine Aktivität während ihrer Lifetime befinden kann. Der Lebenszyklus reicht von dem Zeitpunkt, zu dem die Aktivität erstellt wird, bis zum Löschen dieser Aktivität. Das System beansprucht dann die Ressourcen dieser Aktivität. Wenn ein Nutzer zwischen den Aktivitäten in Ihrer App und zurück und in Ihre App wechselt, wechseln diese Aktivitäten zwischen verschiedenen Status im Aktivitätslebenszyklus.
Der Lebenszyklus eines Fragments ist dem von Aktivitäten sehr ähnlich. Dieses Codelab konzentriert sich hauptsächlich auf Aktivitäten mit einem schnellen Überblick über Fragmente zum Ende.
Als Android-Entwickler müssen Sie den Aktivitätslebenszyklus verstehen. Wenn Ihre Aktivitäten nicht wie vorgesehen auf den Lebenszyklusstatus reagieren, kann es passieren, dass Ihre App seltsame Fehler erzeugt, Nutzer verwirrt oder zu viele Android-Systemressourcen verwendet. Nur wenn Sie ein gutes Android-Gerät entwickeln, können Sie den Lebenszyklus von Android verstehen und richtig auf Veränderungen im Lebenszyklus reagieren.
Wichtige Informationen
- Was ist eine Aktivität und wie wird sie in Ihrer App erstellt?
- Was die
onCreate()
-Methode der Aktivität bewirkt und welche Art von Vorgängen, die bei dieser Methode ausgeführt werden. - Wie Sie XML-Layouts für Ihre Aktivität erstellen und wie Sie ein Layout zur Laufzeit aktualisieren
Lerninhalte
- Informationen zum Drucken von Logging-Informationen an die Logcat (auch Android-Konsole oder Android-Monitor genannt).
- Die Grundlagen des
Activity
- undFragment
-Lebenszyklus und die Callbacks, die aufgerufen werden, wenn die Aktivität zwischen den Status wechselt. - Lebenszyklus-Callback-Methoden überschreiben, um Vorgänge zu verschiedenen Zeiten im Aktivitätslebenszyklus auszuführen.
- Wie Sie die
Timber
-Bibliothek für die Anmeldung in Ihrer App verwenden
Vorgehensweise
- Ändern Sie eine Starter-App namens DessertClicker, um Logging-Informationen hinzuzufügen, die im Logcat angezeigt werden.
- Lebenszyklus-Callback-Methoden überschreiben und Änderungen am Aktivitätsstatus protokollieren.
- Führen Sie die App aus und notieren Sie sich die Logging-Informationen, die angezeigt werden, wenn die Aktivität gestartet, beendet und fortgesetzt wird.
- Ändere die App, um die
Timber
-Bibliothek zu verwenden. - Fügen Sie der AndroidTrivia-App Logging hinzu und behalten Sie Änderungen der Fragmentstatus im Blick.
In diesem Codelab arbeiten Sie mit einer Start-App namens DessertClicker. In dieser App erscheint jedes Mal, wenn der Nutzer auf dem Bildschirm auf ein Dessert tippt, die App mit dem Inhalt des Desserts für den Nutzer. Im Layout der App werden die Werte für die Anzahl der Desserts, die gekauft wurden, und für den Gesamtbetrag, den der Nutzer ausgegeben hat, aktualisiert.
Diese App enthält mehrere Fehler im Zusammenhang mit dem Android-Lebenszyklus: In bestimmten Fällen setzt die App die Dessertwerte auf 0 zurück und die App verwendet weiterhin Systemressourcen, auch wenn sie im Hintergrund ausgeführt wird. Wenn du den Android-Lebenszyklus verstehst, kannst du besser verstehen, warum diese Probleme auftreten und wie du sie beheben kannst.
Jede Aktivität und jedes Fragment hat einen sogenannten Lebenszyklus. Dies ist eine Anspielung auf den Lebenszyklus von Tieren, beispielsweise auf den Lebenszyklus dieses Schmetterlings. Die verschiedenen Schmetterlingsarten zeigen ihren Wachstum von der Geburt bis zum vollständigen Entstehen und bis zum Tod.
Ebenso besteht der Aktivitätslebenszyklus aus den verschiedenen Status, die eine Aktivität durchlaufen kann – von der ersten Initialisierung der Aktivität bis hin zum letzten Löschen und der erneuten Arbeitsspeicherreaktion durch das System. Sobald der Nutzer Ihre App startet, zwischen Apps wechselt und innerhalb und außerhalb der App wechselt, ändert sich der Status der Aktivität. Das folgende Diagramm zeigt den gesamten Lebenszyklus der Aktivitäten. Wie die Namen zeigen, geben diese Status den Status der Aktivität an.
Häufig möchten Sie ein bestimmtes Verhalten ändern oder Code ausführen, wenn sich der Status des Aktivitätslebenszyklus ändert. Daher implementieren die Activity
-Klasse selbst und alle abgeleiteten Klassen von Activity
wie AppCompatActivity
eine Gruppe von Lebenszyklus-Callback-Methoden. Android ruft diese Callbacks auf, wenn eine Aktivität von einem Status in einen anderen wechselt. Sie können diese Methoden dann in Ihren eigenen Aktivitäten überschreiben, um Aufgaben als Reaktion auf diese Änderungen des Lebenszyklusstatus auszuführen. Das folgende Diagramm zeigt den Lebenszyklusstatus sowie die verfügbaren überschreibbaren Callbacks.
Außerdem hat ein Fragment einen Lebenszyklus. Der Lebenszyklus eines Fragments ähnelt einem Lebenszyklus einer Aktivität. Deshalb gilt eine Menge des Gelernten für beides. In diesem Codelab konzentrierst du dich auf den Aktivitätslebenszyklus, da es ein wesentlicher Bestandteil von Android ist und am einfachsten in einer einfachen App zu beobachten ist. Hier ist das entsprechende Diagramm für den Fragmentlebenszyklus:
Es ist wichtig zu wissen, wann diese Callbacks aufgerufen werden und was die jeweiligen Callback-Methode ist. Beide Diagramme sind jedoch komplex und können verwirrend sein. In diesem Codelab lernen Sie nicht nur, was der jeweilige Status und Rückruf bedeutet, sondern führen einige Detektivarbeit durch und verstehen Ihre Kenntnisse.
Schritt 1: Methode „onCreate()“ prüfen und Protokollierung hinzufügen
Um herauszufinden, was beim Android-Lebenszyklus passiert, ist es hilfreich zu wissen, wann die verschiedenen Lebenszyklusmethoden aufgerufen werden. So kannst du in DessertClicker nach möglichen Fehlern suchen.
Die einfache Möglichkeit hierfür ist die Verwendung der Android Logging API. Mithilfe von Logging können Sie kurze Nachrichten in eine Konsole schreiben, während die App ausgeführt wird. Außerdem können Sie sich dort ansehen, wann verschiedene Callbacks ausgelöst werden.
- Lade die DessertClicker App herunter und öffne sie in Android Studio.
- kompiliere und führe die App aus und tippe dann mehrmals auf das Bild des Desserts. Beachten Sie, dass sich der Wert für Desserts Sold (Desserts verkauft) und der Gesamtbetrag ändern.
- Öffnen Sie
MainActivity.kt
und untersuchen Sie dieonCreate()
-Methode für diese Aktivität
override fun onCreate(savedInstanceState: Bundle?) {
...
}
Vielleicht hast du im Diagramm zum Aktivitätslebenszyklus die onCreate()
-Methode erkannt, weil du diesen Callback bereits verwendet hast. Es ist die Methode, die jede Aktivität implementieren muss. Bei der Methode onCreate()
sollten Sie Ihre Initialisierungen einmalig für Ihre Aktivität ausführen. Beispielsweise können Sie in onCreate()
das Layout aufladen, Klick-Listener definieren oder eine Datenbindung einrichten.
Die Lebenszyklusmethode onCreate()
wird einmal aufgerufen, kurz nach der Initialisierung der Aktivität (also wenn das neue Activity
-Objekt im Arbeitsspeicher erstellt wird). Nachdem onCreate()
ausgeführt wurde, gilt die Aktivität als erstellt.
- Fügen Sie in der Methode
onCreate()
direkt nach dem Aufruf vonsuper.onCreate()
die folgende Zeile ein. Importieren Sie gegebenenfalls die KlasseLog
. (Drücken SieAlt+Enter
oderOption+Enter
auf einem Mac und wählen Sie Importieren aus.)
Log.i("MainActivity", "onCreate Called")
Die Klasse Log
schreibt Nachrichten in den Logcat. Dieser Befehl besteht aus drei Teilen:
- Der Schweregrad der Protokollnachricht, d. h. wie wichtig die Nachricht ist. In diesem Fall wird mit der Methode
Log.i()
eine Informationsnachricht geschrieben. Andere Methoden in derLog
-Klasse sindLog.e()
für Fehler oderLog.w()
für Warnungen. - Das Tag im Log, in diesem Fall
"MainActivity"
. Das Tag ist ein String, mit dem Sie Ihre Logeinträge leichter im Logcat finden. Das Tag ist normalerweise der Name der Klasse. - Die tatsächliche Lognachricht, ein kurzer String, der in diesem Fall
"onCreate called"
ist.
- Kompilieren und führen Sie die DessertClicker-App aus. Wenn Sie auf das Dessert tippen, sehen Sie keine Unterschiede der Funktionsweise in der App. Klicken Sie unten in Android Studio auf den Tab Logcat.
Die Logcat ist die Konsole für die Protokollierung von Nachrichten. Hier werden Nachrichten von Android zu deiner App angezeigt, einschließlich der Nachrichten, die du mit derLog.i()
-Methode oder anderenLog
-Klassenmethoden explizit an das Protokoll sendest. - Geben Sie im Bereich Logcat
I/MainActivity
in das Suchfeld ein.
Der Logcat kann viele Nachrichten enthalten, von denen die meisten nicht relevant sind. Sie können die Logcat-Einträge auf viele Arten filtern, aber die Suche ist die einfachste. Weil SieMainActivity
als Log-Tag in Ihrem Code verwendet haben, können Sie dieses Tag zum Filtern des Logs verwenden. Wenn duI/
am Anfang hinzufügst, ist das eine informative Nachricht vonLog.i()
.
Deine Log-Nachricht enthält Datum und Uhrzeit, den Namen des Pakets (com.example.android.dessertclicker
), dein Log-Tag (mitI/
am Anfang) und die eigentliche Nachricht. Da diese Nachricht im Protokoll angezeigt wird, wissen Sie, dassonCreate()
ausgeführt wurde.
Schritt 2: onStart()-Methode implementieren
Die Lebenszyklusmethode onStart()
wird direkt nach onCreate()
aufgerufen. Nachdem onStart()
ausgeführt wurde, sind Ihre Aktivitäten auf dem Bildschirm sichtbar. Im Gegensatz zu onCreate()
, der nur einmal zum Initialisieren Ihrer Aktivität aufgerufen wird, kann onStart()
im Lebenszyklus Ihrer Aktivität oft aufgerufen werden.
Beachten Sie, dass onStart()
mit einer entsprechenden onStop()
-Lebenszyklusmethode gekoppelt ist. Wenn der Nutzer Ihre App startet und dann zum Startbildschirm des Geräts zurückkehrt, wird die Aktivität angehalten und ist nicht mehr auf dem Bildschirm sichtbar.
- Wählen Sie in Android Studio, während
MainActivity.kt
geöffnet ist, Code > Überschreibungsmethoden aus oder drücken SieControl+o
. Es wird ein Dialogfeld mit einer umfangreichen Liste aller Methoden angezeigt, die in diesem Kurs überschrieben werden können. - Gib
onStart
ein, um nach der richtigen Methode zu suchen. Mit dem Abwärtspfeil können Sie zum nächsten übereinstimmenden Element scrollen. Wählen SieonStart()
aus der Liste aus und klicken Sie auf OK, um den Boilerplate-Überschreibungscode einzufügen. Der Code sieht so aus:
override fun onStart() {
super.onStart()
}
- Fügen Sie in der Methode
onStart()
eine Lognachricht hinzu:
override fun onStart() {
super.onStart()
Log.i("MainActivity", "onStart Called")
}
- Kompilieren und führen Sie die DessertClicker-App aus und öffnen Sie den Bereich Logcat. Geben Sie
I/MainActivity
in das Suchfeld ein, um das Protokoll zu filtern. Die MethodenonCreate()
undonStart()
wurden nacheinander aufgerufen und Ihre Aktivitäten sind auf dem Bildschirm sichtbar. - Drücke auf dem Gerät die Startbildschirmtaste und kehre dann mit der zuletzt aufgerufenen Seite zur Aktivität zurück. Die Aktivität wird an der Stelle fortgesetzt, an der sie angehalten wurde. Sie enthält dieselben Werte. Außerdem wird
onStart()
ein zweites Mal in Logcat protokolliert. DieonCreate()
-Methode wird in der Regel nicht noch einmal aufgerufen.
In dieser Aufgabe ändern Sie Ihre Anwendung so, dass eine beliebte Logging-Bibliothek mit dem Namen Timber
verwendet wird. Timber
bietet mehrere Vorteile gegenüber der integrierten Android-Klasse Log
. Insbesondere die Bibliothek Timber
:
- Generiert das Log-Tag basierend auf dem Klassennamen.
- Damit können Sie verhindern, dass Protokolle in einer Release-Version Ihrer Android-App angezeigt werden.
- Ermöglicht die Integration mit Bibliotheken für Absturzberichte.
Den ersten Vorteil siehst du sofort, die anderen von dir schätzen, wenn du größere Apps erstellst und versendet.
Schritt 1: Timer zu Gradle hinzufügen
- Rufen Sie diesen Link zum Timber-Projekt auf GitHub auf und kopieren Sie die Codezeile unter der Überschrift Download, die mit dem Wort
implementation
beginnt. Die Codezeile sieht dann etwa so aus, wobei die Versionsnummer davon abweichen kann.
implementation 'com.jakewharton.timber:timber:4.7.1'
- Maximieren Sie in Android Studio im Bereich „Projekt: Android“ die Option Gradle-Skripts und öffnen Sie die Datei build.gradle (Modul: App).
- Fügen Sie im Abschnitt „Abhängigkeiten“ die kopierte Codezeile ein.
dependencies {
...
implementation 'com.jakewharton.timber:timber:4.7.1'
}
- Klicken Sie rechts oben in Android Studio auf den Link Sync Now (Jetzt synchronisieren), um Gradle neu zu erstellen. Der Build sollte ohne Fehler ausgeführt werden.
Schritt 2: Anwendungsklasse erstellen und Timber initialisieren
In diesem Schritt erstellen Sie eine Application
-Klasse. Application
ist eine Basisklasse, die den globalen Anwendungsstatus für deine gesamte App enthält. Sie ist auch das Hauptobjekt, mit dem das Betriebssystem mit deiner App interagiert. Es gibt eine Application
-Standardklasse, die Android verwendet, wenn du keine App angibst. Es gibt also immer ein Application
-Objekt, das für deine App erstellt wird, ohne dass du etwas spezielles erstellen musst.
Timber
verwendet die Klasse Application
, da die gesamte Anwendung diese Logging-Bibliothek verwendet. Die Bibliothek muss einmal initialisiert werden, bevor alle anderen Funktionen eingerichtet sind. In solchen Fällen kannst du die Klasse Application
blockieren und die Standardeinstellungen mit deiner eigenen benutzerdefinierten Implementierung überschreiben.
Nachdem du die Application
-Klasse erstellt hast, musst du die Klasse im Android-Manifest angeben.
- Erstellen Sie im Paket
dessertclicker
eine neue Kotlin-Klasse mit dem NamenClickerApplication
. Maximieren Sie dazu app > java und klicken Sie mit der rechten Maustaste auf com.example.android.Desserclicker. Wähle Neu > Kotlin-Datei/Kurs aus. - Geben Sie der Klasse den Namen ClickerApplication und legen Sie Kind auf Class fest. Klicken Sie auf OK.
In Android Studio wird eine neue ClickerApplication
-Klasse erstellt und im Code-Editor geöffnet. Der Code sieht so aus:
package com.example.android.dessertclicker
class ClickerApplication {
}
- Ändere die Klassendefinition in eine Unterklasse von
Application
und importiere gegebenenfalls dieApplication
-Klasse.
class ClickerApplication : Application() {
- Wenn Sie die
onCreate()
-Methode überschreiben möchten, wählen Sie Code > Überschreibungsmethoden aus oder drücken SieControl+o
.
class ClickerApplication : Application() {
override fun onCreate() {
super.onCreate()
}
}
- Initialisieren Sie in dieser
onCreate()
-Methode dieTimber
-Bibliothek:
override fun onCreate() {
super.onCreate()
Timber.plant(Timber.DebugTree())
}
Mit dieser Codezeile wird die Bibliothek Timber
für deine App initialisiert, damit du sie in deinen Aktivitäten verwenden kannst.
- Öffnen Sie die Datei AndroidManifest.xml.
- Fügen Sie oben im Element
<application>
ein neues Attribut für die KlasseClickerApplication
hinzu, damit Android weiß, dass anstelle der Standardklasse die KlasseApplication
verwendet wird.
<application
android:name=".ClickerApplication"
...
Schritt 3: Timber-Protokollanweisungen hinzufügen
In diesem Schritt ändern Sie Ihre Log.i()
-Aufrufe, sodass Timber
verwendet wird. Anschließend implementieren Sie das Logging für alle anderen Lebenszyklusmethoden.
- Öffnen Sie
MainActivity
und scrollen Sie zuonCreate()
. Ersetzen SieLog.i()
durchTimber.i()
und entfernen Sie das Log-Tag.
Timber.i("onCreate called")
Wie bei der Log
-Klasse verwendet Timber
auch die i()
-Methode für Informationsnachrichten. Beachten Sie, dass Sie mit Timber
kein Log-Tag hinzufügen müssen. Timber
verwendet automatisch den Namen der Klasse als Log-Tag.
- Oder ändere den
Log
-Aufruf inonStart()
:
override fun onStart() {
super.onStart()
Timber.i("onStart Called")
}
- Kompilieren und führen Sie die DessertClicker-App aus und öffnen Sie Logcat. Beachten Sie, dass Sie für
onCreate()
undonStart()
weiterhin die gleichen Logeinträge sehen, nur aberTimber
, die diese Nachrichten generieren, nicht die KlasseLog
. - Überschreibe die restlichen Lebenszyklusmethoden in deiner
MainActivity
und füge jeweilsTimber
Loganweisungen hinzu. Code:
override fun onResume() {
super.onResume()
Timber.i("onResume Called")
}
override fun onPause() {
super.onPause()
Timber.i("onPause Called")
}
override fun onStop() {
super.onStop()
Timber.i("onStop Called")
}
override fun onDestroy() {
super.onDestroy()
Timber.i("onDestroy Called")
}
override fun onRestart() {
super.onRestart()
Timber.i("onRestart Called")
}
- Kompilieren und führen Sie DessertClicker noch einmal durch und untersuchen Sie Logcat. Dieses Mal gibt es neben
onCreate()
undonStart()
auch eine Protokollnachricht für den Lebenszyklus-CallbackonResume()
.
Wenn eine Aktivität neu beginnt, werden alle drei Lebenszyklus-Callbacks in der angegebenen Reihenfolge angezeigt:
onCreate()
, um die App zu erstellenonStart()
, um ihn zu starten und auf dem Bildschirm sichtbar zu machen.onResume()
, um den Aktivitätsschwerpunkt zu ändern und den Nutzer auf das Ereignis vorzubereiten.
Trotz des Namens wird die onResume()
-Methode beim Start aufgerufen, auch wenn nichts fortgesetzt werden kann.
Nachdem die DessertClicker-App jetzt für die Protokollierung eingerichtet ist, können Sie die Anwendung auf verschiedene Arten verwenden und ermitteln, wie die Lebenszyklus-Callbacks als Reaktion auf diese Verwendungen ausgelöst werden.
Anwendungsfall 1: Öffnen und Schließen der Aktivität
Beginnen Sie mit dem grundlegendsten Anwendungsfall: Sie müssen Ihre App zum ersten Mal starten und dann vollständig schließen.
- Kompilieren und führen Sie die DessertClicker-App aus, falls sie noch nicht ausgeführt wird. Wie Sie sehen, werden die Callbacks
onCreate()
,onStart()
undonResume()
aufgerufen, wenn die Aktivität zum ersten Mal beginnt. - Tippe mehrmals auf Cupcakes.
- Tippen Sie auf dem Gerät auf die Schaltfläche „Zurück“. Beachten Sie in Logcat, dass
onPause()
,onStop()
undonDestroy()
in dieser Reihenfolge aufgerufen werden.
In diesem Fall wird die Aktivität (und die App) über die Schaltfläche „Zurück“ vollständig geschlossen. Durch die Ausführung der MethodeonDestroy()
wurde die Aktivität vollständig beendet und kann automatisch bereinigt werden. Garagentorsammlung bezieht sich auf die automatische Bereinigung von Objekten, die Sie nicht mehr verwenden. Nach dem Aufruf vononDestroy()
weiß das Betriebssystem, dass diese Ressourcen verworfen werden können, und bereinigt den Arbeitsspeicher.
Deine Aktivitäten werden eventuell auch vollständig beendet, wenn dein Code die App manuell mit der Aktivitätfinish()
aufruft oder der Nutzer das Beenden der App erzwingt. So kann er beispielsweise durch Tippen auf das X in der Ecke des Fensters die Beenden der App erzwingen. Das Android-System fährt möglicherweise auch Ihre Aktivitäten selbst herunter, wenn Ihre App längere Zeit nicht auf dem Bildschirm angezeigt wurde. Das trägt dazu bei, dass der Akku geschont wird und die Ressourcen deiner App von anderen Apps genutzt werden können. - Mit dem Bildschirm „Zuletzt verwendet“ kehren Sie zur App zurück. Hier ist die Logcat:
Die Aktivität wurde im vorherigen Schritt gelöscht. Wenn Sie zur App zurückkehren, startet Android eine neue Aktivität und ruft die MethodeonCreate()
,onStart()
undonResume()
auf. Beachten Sie, dass keine der DessertClicker-Statistiken aus der vorherigen Aktivität beibehalten wurde.
Das Wichtigste ist hier, dassonCreate()
undonDestroy()
während der Lifetime einer einzelnen Aktivitätsinstanz nur einmal aufgerufen werden:onCreate()
, um die App zum ersten Mal zu initialisieren, undonDestroy()
, um die von Ihrer App verwendeten Ressourcen zu bereinigen.
DieonCreate()
-Methode ist ein wichtiger Schritt. Hier findet die erstmalige Initialisierung statt, bei der Sie das Layout zum ersten Mal durch Inflieren der Variablen einrichten und wo Sie Ihre Variablen initialisieren.
Anwendungsfall 2: Aktivität verlassen und zurück
Nachdem Sie die App gestartet und vollständig geschlossen haben, haben Sie den Großteil der Lebenszyklusstatus gesehen, wenn die Aktivität zum ersten Mal erstellt wird. Außerdem sehen Sie alle Lebenszyklusphasen, die passieren, wenn die Aktivität vollständig beendet und zerstört wird. Wenn Nutzer jedoch mit ihren Android-Geräten interagieren, wechseln sie zwischen Apps, kehren zur Startseite zurück, starten neue Apps und bewältigen Unterbrechungen durch andere Aktivitäten wie Anrufe.
Ihre Aktivität wird nicht jedes Mal geschlossen, wenn der Nutzer die Aktivität verlässt:
- Wenn deine Aktivitäten nicht mehr auf dem Bildschirm zu sehen sind, wird sie als Hintergrund bezeichnet. Dagegen ist die Aktivität im Vordergrund oder auf dem Bildschirm.
- Wenn der Nutzer zu Ihrer App zurückkehrt, wird diese Aktivität neu gestartet und ist wieder sichtbar. Dieser Teil des Lebenszyklus wird als sichtbarer Lebenszyklus der App bezeichnet.
Wenn Ihre App im Hintergrund ausgeführt wird, sollte sie nicht aktiv ausgeführt werden, um Systemressourcen und die Akkulaufzeit zu verlängern. Du verwendest den Activity
-Lebenszyklus und die zugehörigen Callbacks, um zu erfahren, wann sich deine App in den Hintergrund verschiebt. So kannst du laufende Vorgänge pausieren. Starte den Vorgang dann neu, wenn deine App im Vordergrund ausgeführt wird.
Stellen Sie sich eine App vor, die eine Physiksimulation simuliert. Für die Entscheidung, wo sich alle Objekte in der Simulation befinden, und Anzeige. Wenn die Simulation durch einen Telefonanruf unterbrochen wird, ist der Nutzer möglicherweise verwirrt oder sogar verärgert, sodass er die App zurückspult und sieht, dass die Simulation abgeschlossen ist.
Es gibt auch einen Leistungsgrund dafür. Angenommen, der Nutzer hat 20 Apps geöffnet, in denen CPU-intensive physikalische Simulationen verwendet werden. Wenn diese Apps nicht auf dem Bildschirm zu sehen sind, aber dennoch starke Rendering-Berechnungen im Hintergrund erfolgen, wirkt sich dies negativ auf die Leistung des gesamten Smartphones aus.
In diesem Schritt sehen Sie sich den Aktivitätslebenszyklus an, wenn die App in den Hintergrund verschoben und wieder in den Vordergrund zurückkehrt.
- Klicke während der Ausführung der DessertClicker-App einige Male auf den Cupcake.
- Drücken Sie auf Ihrem Gerät die Startbildschirmtaste und beobachten Sie die Logcat in Android Studio. Wenn Sie zum Startbildschirm zurückkehren, wird die App im Hintergrund ausgeführt und nicht vollständig geschlossen. Die Methode
onPause()
undonStop()
werden aufgerufen,onDestroy()
aber nicht.
WennonPause()
aufgerufen wird, hat die App keinen Fokus mehr. Nach demonStop()
ist die App nicht mehr auf dem Bildschirm sichtbar. Obwohl die Aktivität gestoppt wurde, befindet sich dasActivity
-Objekt noch im Arbeitsspeicher, im Hintergrund. Die Aktivität wurde nicht gelöscht. Der Nutzer kehrt möglicherweise zur App zurück, sodass Android Ihre Aktivitätsressourcen beibehält. - Verwende den Bildschirm „Zuletzt verwendet“, um zur App zurückzukehren. Beachte, dass die Aktivität in Logcat mit
onRestart()
undonStart()
neu gestartet und dann mitonResume()
fortgesetzt wird.
Wenn die Aktivität wieder in den Vordergrund rückt, wird dieonCreate()
-Methode nicht noch einmal aufgerufen. Das Aktivitätsobjekt wurde nicht gelöscht, sodass es nicht noch einmal erstellt werden muss. StattonCreate()
wird die MethodeonRestart()
aufgerufen. Wenn die Aktivität wieder in den Vordergrund rückt, wird die Zahl Verkaufte Träger beibehalten. - Starte mindestens eine andere App als „DessertClicker“, damit auf dem Display des Geräts einige Apps angezeigt werden.
- Rufe den Bildschirm „Zuletzt verwendet“ auf und öffne eine weitere Aktivität. Rufe dann die zuletzt verwendeten Apps auf und setze DessertClicker wieder in den Vordergrund.
Hier siehst du dieselben Callbacks in Logcat wie auf der Startbildschirmtaste.onPause()
undonStop()
werden aufgerufen, wenn die App in den Hintergrund wechselt, und dannonRestart()
,onStart()
undonResume()
, wenn sie ausgeführt wird.
Der wichtige Punkt ist, dassonStart()
undonStop()
mehrmals aufgerufen werden, wenn der Nutzer die Aktivität aufruft und von ihr ausgeht. Sie sollten diese Methoden überschreiben, um die App zu stoppen, wenn sie in den Hintergrund verschoben wird, oder sie neu zu starten, wenn sie wieder in den Vordergrund rückt.
Was ist mitonRestart()
? DieonRestart()
-Methode ist ähnlich wieonCreate()
. EntwederonCreate()
oderonRestart()
wird aufgerufen, bevor die Aktivität sichtbar wird. Die MethodeonCreate()
wird nur beim ersten Mal undonRestart()
danach aufgerufen. Mit deronRestart()
-Methode können Sie Code generieren, den Sie nur dann aufrufen möchten, wenn Ihre Aktivität nicht zum ersten Mal gestartet wird.
Anwendungsfall 3: Aktivität teilweise ausblenden
Du hast gelernt, dass, wenn eine App gestartet wird und onStart()
aufgerufen wird, die App auf dem Bildschirm sichtbar ist. Wenn die App fortgesetzt und onResume()
aufgerufen wird, erhält die App den Nutzerfokus. Der Teil des Lebenszyklus, in dem die App vollständig auf dem Bildschirm erscheint und den Nutzerfokus hat, wird als interaktiver Lebenszyklus bezeichnet.
Wenn die App in den Hintergrund rückt, geht der Fokus nach onPause()
verloren und die App wird nach onStop()
nicht mehr sichtbar sein.
Der Unterschied zwischen Fokus und Sichtbarkeit ist wichtig, da eine Aktivität zwar teilweise auf dem Bildschirm sichtbar sein kann, nicht aber den Nutzerfokus. In diesem Schritt betrachten Sie einen Fall, bei dem eine Aktivität nur teilweise sichtbar ist, aber keinen Nutzerfokus hat.
- Wenn die DessertClicker-App ausgeführt wird, klicken Sie rechts oben auf die Schaltfläche Teilen.
Die Freigabeaktivitäten werden in der unteren Hälfte des Bildschirms angezeigt, die Aktivitäten sind aber weiterhin in der oberen Hälfte sichtbar. - Prüfen Sie Logcat und stellen Sie fest, dass nur
onPause()
aufgerufen wurde.
In diesem Anwendungsfall wirdonStop()
nicht aufgerufen, weil die Aktivität noch teilweise sichtbar ist. Aber diese Aktivität hat keinen Nutzerfokus und der Nutzer kann nicht mit ihm interagieren. Bei der Aktivität „Teilen“ im Vordergrund steht der Nutzer im Fokus.
Warum ist dieser Unterschied wichtig? Denken Sie an die Physik-App. Möglicherweise möchten Sie die Simulation beenden, wenn die App im Hintergrund ausgeführt wird, und sie weiter ausführen, wenn sie teilweise verdeckt ist. In diesem Fall würdest du die Simulation inonStop()
beenden. Wenn du möchtest, dass die Simulation beendet wird, wenn die Aktivität teilweise verdeckt wird, füge den Code ein, um die Simulation inonPause()
zu beenden.
Der Code, der inonPause()
ausgeführt wird, blockiert andere Elemente. Achte also darauf, dass der Code inonPause()
schlank ist. Wenn beispielsweise ein Telefonanruf eingeht, kann der Code inonPause()
die Benachrichtigung für eingehende Anrufe verzögern. - Wenn du außerhalb des Freigabedialogs klickst, kehrst du zur App zurück und siehst, dass
onResume()
aufgerufen wird.
SowohlonResume()
als auchonPause()
müssen sich im Fokus befinden. Die MethodeonResume()
wird aufgerufen, wenn die Aktivität fokussiert ist, undonPause()
, wenn die Aktivität verloren geht.
Der Lebenszyklus von Android-Fragmenten ähnelt dem Aktivitätslebenszyklus und umfasst außerdem mehrere fragmentspezifische Methoden.
In dieser Aufgabe sehen Sie sich die AndroidTrivia-App an, die Sie in früheren Codelabs erstellt haben. Außerdem fügen Sie Logging hinzu, um den Fragmentlebenszyklus zu untersuchen. Mit der AndroidTrivia App können Sie Fragen zur Android-Entwicklung beantworten. Wenn Sie drei Fragen in Folge richtig beantworten, gewinnen Sie das Spiel.
Jeder Bildschirm in der Android Trivia App ist ein Fragment
.
Der Einfachheit halber verwenden Sie für diese Aufgabe die Android Logging API und nicht die Timber-Bibliothek.
- Öffnen Sie die AndroidTrivia-App aus dem letzten Codelab oder laden Sie den AndroidTrivia-Lösungscode von GitHub herunter.
- Öffnen Sie die Datei
TitleFragment.kt
. Hinweis: Android Studio zeigt möglicherweise Bindungsfehler und ungelöste Referenzfehler an, bis du die App neu erstellst. - Scrollen Sie nach unten zur Methode
onCreateView()
. Hier sehen Sie, dass das Layout des Fragments zu hoch ist und eine Datenbindung erfolgt. - Fügen Sie der Methode
onCreateView()
eine Logging-Anweisung hinzu, zwischen der Zeile undsetHasOptionsMenu()
und dem letzten Aufruf, der zurückgegeben werden soll:
setHasOptionsMenu(true)
Log.i("TitleFragment", "onCreateView called")
return binding.root
- Fügen Sie direkt unter der Methode
onCreateView()
Logging-Anweisungen für jede der verbleibenden Fragmentmethoden hinzu. Hier ist der Code:
override fun onAttach(context: Context?) {
super.onAttach(context)
Log.i("TitleFragment", "onAttach called")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.i("TitleFragment", "onCreate called")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.i("TitleFragment", "onActivityCreated called")
}
override fun onStart() {
super.onStart()
Log.i("TitleFragment", "onStart called")
}
override fun onResume() {
super.onResume()
Log.i("TitleFragment", "onResume called")
}
override fun onPause() {
super.onPause()
Log.i("TitleFragment", "onPause called")
}
override fun onStop() {
super.onStop()
Log.i("TitleFragment", "onStop called")
}
override fun onDestroyView() {
super.onDestroyView()
Log.i("TitleFragment", "onDestroyView called")
}
override fun onDetach() {
super.onDetach()
Log.i("TitleFragment", "onDetach called")
}
- Kompilieren und führen Sie die App aus und öffnen Sie Logcat.
- Geben Sie
I/TitleFragment
in das Suchfeld ein, um das Protokoll zu filtern. Nach dem Start der App sieht die Logcat so aus:
Hier siehst du den gesamten Startlebenszyklus des Fragments, einschließlich dieser Callbacks:
onAttach()
: Wird aufgerufen, wenn das Fragment der Inhaberaktivität zugeordnet ist.onCreate()
: Ähnlich wieonCreate()
für die Aktivität wirdonCreate()
für das Fragment aufgerufen, um die erste Fragmenterstellung durchzuführen (außer dem Layout).onCreateView()
: Wird aufgerufen, um das Layout des Fragments zu erhöhen.onActivityCreated()
: Wird aufgerufen, wenn die InhaberaktivitätonCreate()
abgeschlossen ist. Dein Fragment kann erst auf die Aktivität zugreifen, wenn diese Methode aufgerufen wird.onStart()
: Wird aufgerufen, wenn das Fragment sichtbar wird; parallel zu den AktivitätenonStart()
.onResume()
: Wird aufgerufen, wenn das Fragment den Nutzerfokus erhält; parallel zu denonResume()
-Aktivitäten.
- Tippe auf die Schaltfläche Spielen, um zum Quiz zu gelangen, und merke dir jetzt die Logcat.
Beim Öffnen des nächsten Fragments wird das Titelfragment geschlossen und die folgenden Lebenszyklusmethoden werden aufgerufen:
onPause()
: Wird aufgerufen, wenn das Fragment den Nutzerfokus verliert, parallel zu denonPause()
-Aktivitäten.onStop()
: Wird aufgerufen, wenn das Fragment nicht mehr auf dem Bildschirm sichtbar ist; parallel zu denonStop()
-Aktivitäten.onDestroyView()
: Wird aufgerufen, wenn die Ansicht des Fragments nicht mehr benötigt wird, um die mit dieser Ansicht verknüpften Ressourcen zu bereinigen.
- Tippe in der App auf den Aufwärtspfeil (den Pfeil links oben auf dem Bildschirm), um zum Titelfragment zurückzukehren.
diesmal werdenonAttach()
undonCreate()
nicht aufgerufen. Das Fragment-Objekt ist noch vorhanden und ist noch an seine Inhaberaktivität angehängt. Der Lebenszyklus beginnt also wieder mitonCreateView()
. - Drücken Sie die Startbildschirmtaste des Geräts. Im Logcat wird angegeben, dass nur
onPause()
undonStop()
aufgerufen werden. Dabei ist das gleiche Verhalten wie bei der Aktivität: Wenn Sie nach Hause zurückkehren, werden die Aktivität und das Fragment in den Hintergrund verschoben. - Nutze den Bildschirm „Zuletzt verwendet“, um zur App zurückzukehren. Genau wie bei der Aktivität werden die Methoden
onStart()
undonResume()
aufgerufen, um das Fragment im Vordergrund anzuzeigen.
Android Studio-Projekt: DessertClickerLogs
Lebenszyklus der Aktivität
- Der Aktivitätslebenszyklus besteht aus mehreren Status, über die eine Aktivität migriert wird. Der Aktivitätslebenszyklus beginnt mit dem ersten Erstellen der Aktivität und endet mit dem Löschen der Aktivität.
- Wenn der Nutzer zwischen Aktivitäten und innerhalb und außerhalb Ihrer App wechselt, wechselt jede Aktivität zwischen den Status im Lebenszyklus der Aktivität.
- Für jeden Status im Aktivitätslebenszyklus gibt es eine entsprechende Callback-Methode, die Sie in Ihrer
Activity
-Klasse überschreiben können. Es gibt sieben Lebenszyklusmethoden:onCreate()
onStart()
onPause()
onRestart()
onResume()
onStop()
onDestroy()
- zum Hinzufügen von Verhalten, das zu einem Übergang zu einer Lebenszyklusphase führt, überschreiben Sie die Callback-Methode des Status.
- Wenn Sie den Klassen in Android Studio Methoden zum Überschreiben von Skeleton hinzufügen möchten, wählen Sie Code > Überschreibungsmethoden aus oder drücken Sie
Control+o
.
Protokollierung mit Log
- Mit der Android Logging API, insbesondere der Klasse
Log
, kannst du kurze Nachrichten schreiben, die in Android in der Logcat angezeigt werden. - Mit
Log.i()
eine Informationsnachricht schreiben. Diese Methode verwendet zwei Argumente: das Tag des Log-Tags (in der Regel der Name der Klasse) und das Log-Tag message (ein kurzer String). - Verwenden Sie in Android Studio den Bereich Logcat, um die Systemprotokolle einschließlich der Meldungen zu sehen, die Sie schreiben.
Protokollierung mit Timber
Timber
ist eine Logging-Bibliothek mit mehreren Vorteilen gegenüber der Android Logging API. Insbesondere die Bibliothek Timber
:
- Generiert das Log-Tag basierend auf dem Klassennamen.
- Kann helfen, Protokolle in einer Release-Version Ihrer Android-App anzuzeigen.
- Ermöglicht die Integration mit Bibliotheken für Absturzberichte.
Wenn du Timber
verwenden möchtest, musst du die Abhängigkeit deiner Gradle-Datei hinzufügen und die Klasse Application
zur Initialisierung der Erweiterung erweitern:
Application
ist eine Basisklasse, die den globalen Anwendungsstatus für deine gesamte App enthält. Es gibt eineApplication
-Standardklasse, die von Android verwendet wird, wenn du keine Klasse angibst. Sie können Ihre eigene UnterklasseApplication
erstellen, um App-weite Bibliotheken wieTimber
zu initialisieren.- Füge deiner App deine benutzerdefinierte
Application
-Klasse hinzu, indem du im Android-Manifest dem<application>
-Element das Attributandroid:name
hinzufügst. Vergiss das nicht! - Mit
Timber.i()
Logeinträge mitTimber
schreiben. Diese Methode verwendet nur ein Argument: die zu schreibende Nachricht. Das Log-Tag (der Name der Klasse) wird automatisch hinzugefügt.
Udacity-Kurs:
Android-Entwicklerdokumentation:
- Aktivitäten (API-Leitfaden)
- Fragments (API-Leitfaden)
Activity
(API-Referenz)Fragment
(API-Referenz)- Informationen zum Aktivitätslebenszyklus
- Logs mit Logcat schreiben und ansehen
Log
(API-Referenz)
Sonstiges:
- Timber (GitHub)
- Der Android-Lebenszyklus auf einen Blick – Teil I: Hier findest du eine Zusammenfassung der Inhalte.
- Im Android-Lebenszyklus auf einen Blick – Teil II: Mehrere Aktivitäten zeigt die Reihenfolge von Lebenszyklusaufrufen, wenn zwei Aktivitäten interagieren.
- Im Android-Lebenszyklus auf einen Blick – Teil III: Fragmente zeigt die Reihenfolge von Lebenszyklusaufrufen, wenn eine Aktivität und ein Fragment interagieren.
In diesem Abschnitt werden mögliche Hausaufgaben für Schüler oder Studenten aufgeführt, die an diesem von einem Kursleiter geleiteten Codelab arbeiten. Die Lehrkraft kann Folgendes tun:
- Bei Bedarf können Sie die entsprechenden Aufgaben zuweisen.
- Schülern mitteilen, wie sie Aufgaben für die Aufgabe abgeben
- Benoten Sie die Hausaufgaben.
Lehrkräfte können diese Vorschläge so oft oder so oft verwenden, wie sie möchten. anderen Aufgaben können sie nach Belieben zugewiesen werden.
Wenn Sie alleine an diesem Codelab arbeiten, können Sie Ihr Wissen mit diesen Hausaufgaben testen.
Eine App ändern
Öffnen Sie die DiceRoller App aus Lektion 1. Hier können Sie die DiceRoller-App herunterladen. Fügen Sie dieser App Timber-Unterstützung hinzu. Gehen Sie dabei genauso vor wie bei der DessertClicker-App. Überschreiben Sie alle Lebenszyklus-Callbacks und fügen Sie für jeden Callback Logging-Nachrichten hinzu.
Diese Fragen beantworten
Frage 1
Welche der folgenden Optionen ist KEIN Status für einen Aktivitätslebenszyklus?
- Gestartet
- Warten
- Erstellt
- Gelöscht
Frage 2
Mit welcher Lebenszyklusmethode wird eine Aktivität sichtbar?
onPause()
onVisible()
onStart()
onDestroy()
Frage 3
Welche Lebenszyklusmethode wird aufgerufen, um einen Aktivitätsschwerpunkt zu erreichen?
onResume()
onVisible()
onStart()
onFocus()
Frage 4
Wann wird onCreate()
in einer Aktivität aufgerufen?
- Jedes Mal, wenn die Aktivität für den Nutzer sichtbar ist.
- Jedes Mal, wenn die Aktivität im Hintergrund auftritt.
- Nur einmal, wenn die Aktivität erstellt wird.
- Nur einmal, wenn die Aktivität fortgesetzt wird.
App zur Benotung einreichen
Prüfen Sie, ob die App die folgenden Anforderungen erfüllt:
- Eine Abhängigkeit von
Timber
in derbuild.gradle
-Datei für die App. - Eine benutzerdefinierte Unterklasse von
Application
, dieTimber
inonCreate()
initialisiert. - Ein Attribut für diese benutzerdefinierte Unterklasse im Android-Manifest.
- Die Methode wird in
MainActivity
für alle Lebenszyklus-Callback-Methoden überschrieben, mit Logging-Aufrufen fürTimber.i()
.
Mit der nächsten Lektion beginnen:
Links zu anderen Codelabs in diesem Kurs finden Sie auf der Landingpage zu Kotlin-Grundlagen für Android.