Aktivitätslebenszyklus

Wenn ein Nutzer durch Ihre App navigiert, wieder verlässt und zu Ihrer App zurückkehrt, Activity Instanzen in Ihrer Anwendung wechseln durch verschiedene Stadien in ihrem Lebenszyklus. Die Klasse Activity bietet eine Reihe von Callbacks. die die Aktivität informieren, wenn sich ein Status ändert eine Aktivität erstellt, beendet, wieder aufnimmt oder den Prozess, in dem sich die Aktivität befindet.

Innerhalb der Lebenszyklus-Callback-Methoden können Sie angeben, verhält sich, wenn der Nutzer die Aktivität verlässt und wieder aufnimmt. Wenn Sie zum Beispiel Streaming-Videoplayer erstellen, können Sie das Video anhalten und die Wiedergabe Netzwerkverbindung, wenn der Nutzer zu einer anderen App wechselt. Wenn Nutzende zurückkehren, kannst du dich wieder mit dem Netzwerk verbinden und der Nutzer kann das Video an der gleichen Stelle.

Mit jedem Callback können Sie bestimmte Aufgaben die für eine bestimmte Statusänderung angemessen ist. Die richtige Arbeit auf der rechten Seite und die korrekte Verarbeitung von Übergängen machen Ihre App robuster und leistungsfähiger. Eine gute Implementierung der Lebenszyklus-Callbacks kann Ihrer App beispielsweise dabei helfen, Vermeiden Sie Folgendes:

  • Absturz, wenn der Nutzer einen Anruf erhält oder zu einem anderen wechselt während Sie Ihre App nutzen.
  • Verbrauch wertvoller Systemressourcen, wenn der Nutzer nicht aktiv ist verwenden.
  • Der Fortschritt des Nutzers geht verloren, wenn er die App verlässt und zu zu einem späteren Zeitpunkt erstellen.
  • Absturz des Nutzers oder Verlieren des Fortschritts beim Drehen des Bildschirms Hoch- und Querformat auswählen.

In diesem Dokument wird der Aktivitätslebenszyklus ausführlich erläutert. Das Dokument beginnt indem sie das Lebenszyklusparadigma beschreiben. Als Nächstes werden die einzelnen Callbacks erläutert: was intern während der Ausführung geschieht und was Sie während des gesamten Projekts.

Anschließend wird kurz die Beziehung zwischen den Aktivitäten und die Anfälligkeit eines Prozesses, durch das System getötet zu werden. Schließlich werden mehrere Themen im Zusammenhang mit Übergängen zwischen Aktivitätsstatus.

Informationen zum Umgang mit Lebenszyklen, einschließlich Anleitungen zum Best Practices finden Sie unter Lebenszyklen mit lebenszyklusbezogenen Komponenten verarbeiten und UI-Status speichern Erfahren Sie, wie Sie mithilfe von Aktivitäten in mit Architekturkomponenten kombinieren, siehe Leitfaden zur Anwendungsarchitektur

Konzepte des Aktivitätslebenszyklus

Für die Navigation zwischen den Phasen des Aktivitätslebenszyklus Die Klasse Activity bietet einen Satz von sechs Callbacks: onCreate(), onStart(), onResume(), onPause(), onStop() und onDestroy() Das System ruft jeden dieser Callbacks angezeigt, wenn die Aktivität in einen neuen Status wechselt.

Abbildung 1 zeigt eine visuelle Darstellung dieses Modells.

Abbildung 1: Eine vereinfachte Darstellung des Aktivitätslebenszyklus.

Wenn der Nutzer beginnt, die Aktivität zu verlassen, ruft das System Methoden auf. um die Aktivität zu demontieren. In einigen Fällen ist die Aktivität nur teilweise auseinandergebaut und befindet sich noch im Speicher, beispielsweise wenn der Nutzer eine andere App. In diesen Fällen kann die Aktivität dennoch wieder in den Vordergrund geleitet werden.

Wenn der Nutzer zur Aktivität zurückkehrt, wird an der Stelle fortgesetzt, an der der Nutzer aufgehört hat. Von wenigen Ausnahmen abgesehen, eingeschränkt von Starten von Aktivitäten im Hintergrund

Die Wahrscheinlichkeit, dass das System die Tötung eines bestimmten Prozesses und die damit verbundenen Aktivitäten vom Staat und dessen der Aktivität zu diesem Zeitpunkt. Weitere Informationen zur Beziehung zwischen Bundesstaat und Sicherheitslücken finden Sie im Abschnitt Aktivitätsstatus und Ausschluss aus dem Speicher.

Je nach Komplexität Ihrer Aktivität müssen Sie Implementierung aller Lebenszyklusmethoden. Es ist jedoch wichtig, dass Sie alle verstehen und implementieren, die das Verhalten Ihrer App beeinflussen, den Erwartungen der Nutzenden entsprechen.

Lebenszyklus-Callbacks

Dieser Abschnitt enthält Informationen zu Konzepten und zur Implementierung der Callback-Methoden, die während des Aktivitätslebenszyklus verwendet werden.

Einige Aktionen gehören zu den Methoden des Aktivitätslebenszyklus. Ortscode jedoch das die Aktionen einer abhängigen Komponente im Komponente und nicht die Methode für den Aktivitätslebenszyklus. Um dies zu erreichen, müssen Sie um den Lebenszyklus der abhängigen Komponente bewusst zu gestalten. Um zu erfahren, wie Sie Lebenszyklus-sensitiven abhängigen Komponenten; siehe Lebenszyklen mit lebenszyklusbezogenen Komponenten verarbeiten

onCreate()

Sie müssen diesen Callback implementieren, der ausgelöst wird, wenn das System zum ersten Mal den Aktivitäten. Beim Erstellen der Aktivität erhält die Aktivität den Status Erstellt. Im onCreate() eine grundlegende Startlogik für Anwendungen auszuführen, nur einmal während der Lebensdauer der Aktivität.

Beispiel: Ihre Die Implementierung von onCreate() kann Daten an Listen binden, die Aktivität mit einem ViewModel, und instanziieren Sie einige Variablen mit Klassenumfang. Diese Methode empfängt die Parameter savedInstanceState, der ein Bundle ist Objekt, das den zuvor gespeicherten Status der Aktivität enthält. Wenn die Aktivität noch nie existiert hat, ist der Wert des Bundle-Objekts null.

Wenn Sie eine Komponente haben, die den Lebenszyklus berücksichtigt, erhält er die ON_CREATE . Die mit @OnLifecycleEvent annotierte Methode wird aufgerufen, Komponente kann jeden Einrichtungscode ausführen, den sie für den erstellten Status benötigt.

Das folgende Beispiel für die Methode onCreate() zeigt die grundlegende Konfiguration der Aktivität, z. B. die Deklaration der Benutzeroberfläche (in einer XML-Layoutdatei definiert), Mitgliedsvariablen definieren und einige Bereiche der Benutzeroberfläche. In diesem Beispiel übergibt die XML-Layoutdatei den Ressourcen-ID der Datei R.layout.main_activity in setContentView().

Kotlin

lateinit var textView: TextView

// Some transient state for the activity instance.
var gameState: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState)

    // Recover the instance state.
    gameState = savedInstanceState?.getString(GAME_STATE_KEY)

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity)

    // Initialize member TextView so it is available later.
    textView = findViewById(R.id.text_view)
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
override fun onSaveInstanceState(outState: Bundle?) {
    outState?.run {
        putString(GAME_STATE_KEY, gameState)
        putString(TEXT_VIEW_KEY, textView.text.toString())
    }
    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState)
}

Java

TextView textView;

// Some transient state for the activity instance.
String gameState;

@Override
public void onCreate(Bundle savedInstanceState) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState);

    // Recover the instance state.
    if (savedInstanceState != null) {
        gameState = savedInstanceState.getString(GAME_STATE_KEY);
    }

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity);

    // Initialize member TextView so it is available later.
    textView = (TextView) findViewById(R.id.text_view);
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putString(GAME_STATE_KEY, gameState);
    outState.putString(TEXT_VIEW_KEY, textView.getText());

    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState);
}

Anstatt die XML-Datei zu definieren und an setContentView() zu übergeben, können Sie können neue View-Objekte in Ihrem Aktivitätscode erstellen und ein Ansicht der Hierarchie durch Einfügen neuer View-Objekte in eine ViewGroup. Dann verwenden Sie dieses Layout, indem Sie den Parameter Stamm ViewGroup in setContentView(). Weitere Informationen zum Erstellen einer Benutzeroberfläche finden Sie in der Dokumentation zur Benutzeroberfläche.

Ihre Aktivitäten verbleiben nicht im Bundesstaat. Nachdem die Methode onCreate() ausgeführt wurde, tritt die Aktivität in den Bereich Gestartet ein. und das System ruft die onStart() und onResume()-Methoden schnell und einfach Abfolge zu lösen.

onStart()

Wenn die Aktivität in den Status „Gestartet“ wechselt, sieht das System ruft onStart() auf. Durch diesen Aufruf wird die Aktivität für den Nutzer Die App bereitet sich darauf vor, dass die Aktivität in den Vordergrund eintritt und interaktiv wird. Bei dieser Methode wird beispielsweise der Code, die UI initialisiert wird.

Wenn die Aktivität in den Status „Gestartet“ wechselt, sind alle lebenszyklusbezogenen Komponenten des Lebenszyklus der Aktivität Ereignis ON_START.

Die Methode onStart() wird abgeschlossen schnell und wie beim Status "Created" (Erstellt) wird die Aktivität nicht im Status „Gestartet“. Sobald dieser Callback beendet ist, tritt die Aktivität in den Fortsetzung onResume()-Methode.

onResume()

Wenn die Aktivität in den Status „Fortsetzen“ wechselt, erscheint sie in den Vordergrund und ruft das System die onResume() auf. Callback des Nutzers an. Dies ist der Status, in dem die App mit den Nutzenden interagiert. Die App bleibt in diesem Status, bis etwas passiert wird der Fokus von der App abgelenkt – z. B. auf dem Gerät, das einen Telefonanruf empfängt, der Nutzer oder zu einer anderen Aktivität navigiert oder der Bildschirm des Geräts ausgeschaltet wird.

Wenn die Aktivität in den Status „Fortgesetzt“ wechselt, sind alle lebenszyklusbezogenen Komponenten des Lebenszyklus der Aktivität ON_RESUME . Hier können die Lebenszykluskomponenten alle Funktionen ermöglichen, die während Die Komponente ist sichtbar und im Vordergrund, z. B. wenn die Kamera gestartet wird. in der Vorschau ansehen.

Wenn ein unterbrechendes Ereignis eintritt, tritt die Aktivität in den Bereich Pausiert ein. und das System ruft die onPause()-Callback.

Wenn die Aktivität wieder wenn der Status „Pausiert“ lautet, ruft das System wieder die Methode onResume()-Methode. Daher sollten Sie onResume() zum Initialisieren von Komponenten, die du während onPause() und jede andere Initialisierungen, die jedes Mal erfolgen müssen, wenn die Aktivität in den Bundesstaat.

Hier ist ein Beispiel für eine Lebenszyklus-orientierte Komponente, die auf die Kamera zugreift, wenn sie Die Komponente empfängt das Ereignis ON_RESUME:

Kotlin

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun initializeCamera() {
        if (camera == null) {
            getCamera()
        }
    }
    ...
}

Java

public class CameraComponent implements LifecycleObserver {

    ...

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void initializeCamera() {
        if (camera == null) {
            getCamera();
        }
    }
    ...
}

Mit dem vorherigen Code wird die Kamera initialisiert, sobald die LifecycleObserver empfängt das Ereignis ON_RESUME. Im Mehrfenstermodus hingegen kann auch im Status „Pausiert“ vollständig sichtbar sein. Wenn beispielsweise befindet sich die App im Mehrfenstermodus und der Nutzer tippt auf das Fenster, Ihre Aktivität enthalten, wird sie in den Status „Pausiert“ versetzt.

Wenn Sie möchten, dass die Kamera nur dann aktiv ist, wenn die App fortgesetzt wird (sichtbar und im Vordergrund aktiv ist, und initialisieren Sie die Kamera, nachdem ON_RESUME Ereignis die zuvor gezeigt wurden. Soll die Kamera während der Aktivität aktiv bleiben? angehalten, aber sichtbar ist (z. B. im Mehrfenstermodus), dann Initialisieren Sie die Kamera nach dem ON_START-Ereignis.

Das Vorhandensein der Kamera aktiv ist, während deine Aktivität pausiert ist, kann eine andere Kamera App im Mehrfenstermodus fortgesetzt. Manchmal ist es notwendig, die Kamera aktiv ist, während die Aktivität pausiert ist. der User Experience insgesamt.

Überlegen Sie sich deshalb genau, Lebenszyklus ist es am sinnvollsten, die Kontrolle über freigegebene Systemressourcen in mehr über den Mehrfenstermodus erfahren. Weitere Informationen zur Unterstützung des Mehrfenstermodus Weitere Informationen zur Unterstützung des Mehrfenstermodus

Unabhängig davon, für welches Aufbauereignis Sie sich entscheiden, Initialisierung abgeschlossen, verwenden Sie unbedingt den entsprechenden um die Ressource freizugeben. Wenn Sie etwas nach dem ON_START-Ereignis, geben Sie es frei oder beenden Sie es nach dem Ereignis vom Typ ON_STOP. Wenn Sie nach dem ON_RESUME-Ereignis initialisieren, nach dem Ereignis vom Typ ON_PAUSE.

Das obige Code-Snippet platziert den Initialisierungscode der Kamera in einem Lebenszyklus-bewusste Komponente. Sie können diesen Code stattdessen direkt in die Aktivität einfügen, Lebenszyklus-Callbacks wie onStart() und onStop(). Dies wird jedoch nicht empfohlen. Diese Logik hinzufügen Lebenszyklus-bewusste Komponente verknüpft ist, können Sie die Komponente über mehrere Aktivitäten hinweg ausführen, ohne Code duplizieren zu müssen. Informationen zum Erstellen einer lebenszyklusbezogenen Komponente finden Sie unter Lebenszyklen mit lebenszyklusbezogenen Komponenten verarbeiten

onPause()

Das System ruft diese Methode als ersten Hinweis darauf ab, dass der Nutzer Ihre Aktivität, obwohl dies nicht immer bedeutet, dass die Aktivität zerstört wird. Die Aktivität wird nicht mehr im Vordergrund ausgeführt, weiterhin sichtbar ist, wenn sich der Nutzer im Mehrfenstermodus befindet. Es gibt mehrere Gründe, warum eine Aktivität diesem Bundesstaat:

  • Ein Ereignis, das die App-Ausführung stört, wie im Abschnitt über onResume()-Rückruf pausiert die aktuelle Aktivität. Dies ist die häufigste Fall.
  • Im Mehrfenstermodus liegt nur eine App im Fokus und das System pausiert alle anderen Apps.
  • Das Öffnen einer neuen, halbtransparenten Aktivität, z. B. eines Dialogfelds, die ausgeführte Aktivität pausiert. Solange wenn die Aktivität nur teilweise sichtbar ist, aber nicht im Fokus ist, bleibt pausiert.

Wenn eine Aktivität in den Status „Pausiert“ wechselt, werden alle lebenszyklusbezogenen Komponenten des Lebenszyklus der Aktivität Ereignis ON_PAUSE. Hier finden Sie können die Lebenszykluskomponenten alle Funktionen stoppen, die nicht ausgeführt werden müssen. wenn sich die Komponente nicht im Vordergrund befindet, z. B. wenn die Kamera in der Vorschau ansehen.

Verwenden Sie die Methode onPause(), um Vorgänge anpassen, die nicht fortgesetzt werden können oder möglicherweise in Moderation fortgesetzt werden, solange Activity sich im Status „Pausiert“ befindet und Sie wird voraussichtlich bald fortgesetzt.

Sie können auch die Methode onPause() verwenden, um Systemressourcen, Griffen an Sensoren (wie GPS) oder andere Ressourcen wirken sich auf die Akkulaufzeit aus, solange die Aktivität pausiert ist und der Nutzer sie brauchen.

Wie jedoch im Abschnitt über onResume() erwähnt, ist eine Pause Die Aktivitäten sind möglicherweise noch vollständig sichtbar, wenn sich die App im Mehrfenstermodus befindet. Zum vollständigen Freigeben oder Anpassen sollten Sie onStop() statt onPause() verwenden UI-bezogene Ressourcen und Vorgänge zur besseren Unterstützung des Mehrfenstermodus

Im folgenden Beispiel für ein LifecycleObserver-Element auf das ON_PAUSE-Ereignis reagieren, ist das Gegenstück zur vorigen Beispiel für ein ON_RESUME-Ereignis, bei dem die Kamera freigegeben wird, die nach dem Das Ereignis ON_RESUME wurde empfangen:

Kotlin

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun releaseCamera() {
        camera?.release()
        camera = null
    }
    ...
}

Java

public class JavaCameraComponent implements LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void releaseCamera() {
        if (camera != null) {
            camera.release();
            camera = null;
        }
    }
    ...
}

In diesem Beispiel wird der Kamera-Freigabecode hinter dem Das ON_PAUSE-Ereignis wird vom LifecycleObserver empfangen.

Die Ausführung von onPause() ist sehr kurz und bietet nicht unbedingt genug Zeit, um Speichervorgänge auszuführen. In diesem Fall Verwenden Sie onPause() nicht, um eine Anwendung oder einen Nutzer zu speichern. Daten, Netzwerkaufrufe oder Datenbanktransaktionen. Solche Arbeiten sind möglicherweise bevor die Methode abgeschlossen wird.

Führen Sie stattdessen intensive Vorgänge zum Herunterfahren während onStop() Weitere Informationen zu geeigneten Vorgängen während onStop(), siehe nächster Abschnitt. Weitere Informationen zum Speichern finden Sie im Abschnitt zum Speichern und Wiederherstellen des Status.

Abschluss der Methode onPause() bedeutet nicht, dass die Aktivität den Status "Pausiert" wechselt. Vielmehr muss die Aktivität bleibt in diesem Zustand, bis die Aktivität fortgesetzt wird oder vollständig die für den Nutzer unsichtbar sind. Wird die Aktivität fortgesetzt, ruft das System erneut onResume()-Callback

Wenn die wenn die Aktivität wieder vom Status „Pausiert“ in den Status „Wiederaufnahme“ zurückkehrt, die Instanz Activity im Arbeitsspeicher, unter Rückruf wenn das System onResume() aufruft. In diesem Szenario müssen Sie keine Komponenten neu initialisieren, die während einer der -Rückrufmethoden, die zum Status "Fortsetzen" führen. Wenn die Aktivität vollständig unsichtbar ist, ruft das System onStop()

onStop()

Wenn Ihre Aktivitäten nicht mehr für den Nutzer sichtbar sind, erscheinen sie Stopped zurück und das System ruft den onStop()-Callback. Dies kann vorkommen, wenn eine neu gestartete Aktivität den gesamten Bildschirm abdeckt. Die das System ruft auch onStop() an Die Aktivität ist beendet und wird demnächst beendet.

Wenn die Aktivität in den Status „Angehalten“ wechselt, werden alle lebenszyklusbezogenen Komponenten des Lebenszyklus der Aktivität Ereignis ON_STOP. Hier finden Sie können die Lebenszykluskomponenten alle Funktionen stoppen, die nicht ausgeführt werden müssen. während die Komponente nicht auf dem Bildschirm sichtbar ist.

In der Methode onStop() loslassen oder anpassen Ressourcen, die nicht benötigt werden, solange die App für den Nutzer nicht sichtbar ist. Ihre App könnte beispielsweise können Sie Animationen pausieren oder von detaillierten zu ungenauen Standortaktualisierungen wechseln. Mit onStop() statt onPause() Das bedeutet, dass die UI-bezogene Arbeit auch dann fortgesetzt wird, wenn der Nutzer Ihre Aktivität im Mehrfenstermodus ansieht. .

Außerdem onStop() verwenden relativ CPU-intensive Vorgänge zum Herunterfahren durchführen. Wenn beispielsweise finden Sie keinen besseren Zeitpunkt, um Informationen in einer Datenbank zu speichern, können Sie dies im onStop() tun. Die folgendes Beispiel zeigt eine Implementierung onStop(), die den Inhalt eines Entwurfsnotiz für nichtflüchtigen Speicher:

Kotlin

override fun onStop() {
    // Call the superclass method first.
    super.onStop()

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    val values = ContentValues().apply {
        put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText())
        put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle())
    }

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate(
            token,     // int token to correlate calls
            null,      // cookie, not used here
            uri,       // The URI for the note to update.
            values,    // The map of column names and new values to apply to them.
            null,      // No SELECT criteria are used.
            null       // No WHERE columns are used.
    )
}

Java

@Override
protected void onStop() {
    // Call the superclass method first.
    super.onStop();

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate (
            mToken,  // int token to correlate calls
            null,    // cookie, not used here
            uri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
    );
}

Im vorherigen Codebeispiel wird SQLite direkt verwendet. Wir empfehlen jedoch die Verwendung von eine Persistenzbibliothek, die eine Abstraktionsschicht über SQLite bereitstellt. Weitere Informationen Weitere Informationen zu den Vorteilen und zur Implementierung in der App sieh dir die Raumpersistenzbibliothek .

Wenn Ihre Aktivität in den Status „Angehalten“ wechselt, wird die Activity Objekt wird im Arbeitsspeicher beibehalten: Es behält alle Status und Mitglieder bei. Informationen, ist aber nicht mit dem Fenstermanager verknüpft. Wenn die Aktivität werden sich diese Informationen an diese Informationen erinnern.

Sie müssen sich Komponenten neu initialisieren, die während einer der Callback-Methoden erstellt wurden bis zum Status "Fortsetzen". Das System erfasst auch den aktuellen für jedes View-Objekt im Layout. Wenn also der Nutzer Text in ein EditText-Widget eingibt, bleiben erhalten, sodass Sie sie nicht speichern oder wiederherstellen müssen.

Hinweis : Sobald Ihre Aktivität beendet wurde, den Prozess, der die Aktivität enthält, zerstören kann, falls das System Arbeitsspeicher wiederherstellen. Auch wenn das System den Prozess zerstört, während die Aktivität angehalten wird, behält das System weiterhin den Status von View bei. wie Text in einem EditText-Widget in einem Bundle (ein Blob aus Schlüssel/Wert-Paaren) und stellt sie wieder her wenn die Nutzenden zur Aktivität zurückkehren. Für Weitere Informationen zum Wiederherstellen einer Aktivität, zu der ein Nutzer zurückkehrt, finden Sie in den Abschnitt zum Speichern und Wiederherstellen des Status.

Im Status „Angehalten“ interagiert die Aktivität entweder wieder mit dem oder die Aktivität wird beendet und verschwindet. Wenn die Aktivität ruft das System onRestart() auf. Wenn die Ausführung von Activity abgeschlossen ist, ruft das System onDestroy().

onDestroy()

onDestroy() wird vor dem Aufruf Aktivitäten vernichtet. Das System ruft diesen Callback aus einem von zwei Gründen auf:

  1. Die Aktivität wird abgeschlossen, da der Nutzer die Aktivitäten oder aufgrund von finish() wird gerade die Aktivität aufgerufen hat.
  2. Das System zerstört die Aktivität aufgrund einer Konfiguration vorübergehend ändern, z. B. zum Drehen des Geräts oder Wechseln in den Mehrfenstermodus.

Wenn die Aktivität in den gelöschten Zustand übergeht, verbinden alle Lebenszykluskomponenten des Lebenszyklus der Aktivität Ereignis ON_DESTROY. Hier finden Sie Lebenszykluskomponenten können alles bereinigt werden, was vor der Ausführung Activity wurde gelöscht.

Anstatt eine Logik in Activity einzufügen, um zu ermitteln, warum er zerstört wird, Verwenden Sie ein ViewModel-Objekt, um den Parameter relevante Datenansichtsdaten für Activity. Wenn Activity neu erstellt wird muss das ViewModel nichts unternehmen, da Sie wird beibehalten und der nächsten Activity-Instanz übergeben.

Wenn das Activity nicht neu erstellt wird, hat das ViewModel den Wert onCleared() aufgerufen, wobei alle benötigten Daten vor der Vernichtung bereinigt werden. Sie können zwischen diesen beiden Szenarien mithilfe der isFinishing()-Methode.

Wenn die Aktivität abgeschlossen ist, ist onDestroy() der letzte Lebenszyklus-Callback Aktivität erfasst. Wenn onDestroy() als Ergebnis einer Konfiguration aufgerufen wird erstellt das System sofort eine neue Activity-Instanz und ruft dann <ph type="x-smartling-placeholder"></ph> onCreate() für diese neue Instanz in der neuen Konfiguration.

Der onDestroy()-Callback gibt alle Ressourcen frei, die von zuvor nicht freigegeben wurden. Callbacks wie onStop()

Aktivitätsstatus und Ausschluss aus dem Arbeitsspeicher

Das System beendet Prozesse, wenn RAM freigegeben werden muss. Die Wahrscheinlichkeit, dass das System Das Beenden eines bestimmten Prozesses hängt vom jeweiligen Status des Prozesses zum jeweiligen Zeitpunkt ab. Prozessstatus, hängt wiederum vom Status der Aktivität ab, die während des Prozesses ausgeführt wird. Tabelle 1 zeigt die Korrelationen zwischen Prozessstatus, Aktivität Status und die Wahrscheinlichkeit, dass das System den Prozess beendet. Diese Tabelle gilt nur, wenn ein Prozess keine anderen Arten von Anwendungskomponenten.

Wahrscheinlichkeit eines Todes Verarbeitungsstatus Endgültiger Aktivitätsstatus
Niedrigste Vordergrund (im Fokus stehen oder kurz davor) Fortgesetzt
Tief Sichtbar (kein Fokus) Gestartet/Pausiert
Höher Hintergrund (unsichtbar) Gestoppt
Höchste Leer Zerstört

Tabelle 1 Beziehung zwischen Prozesslebenszyklus und Aktivitätsstatus.

Das System beendet niemals eine Aktivität direkt, um Arbeitsspeicher freizugeben. Stattdessen werden sie bricht den Prozess ab, in dem die Aktivität ausgeführt wird, und zerstört nicht nur die Aktivität sondern auch für alle anderen Prozesse. Um zu erfahren, wie Sie und den UI-Status deiner Aktivität wiederherstellen, wenn ein vom System initiierter Prozess beendet wird finden Sie im Abschnitt zum Speichern und Wiederherstellen des Status.

Der Nutzer kann einen Prozess auch mit dem Anwendungsmanager unter „Settings“ (Einstellungen) beenden. um die entsprechende App zu beenden.

Weitere Informationen zu Prozessen finden Sie unter Prozesse und Threads Übersicht.

Vorübergehenden UI-Status speichern und wiederherstellen

Ein Nutzer erwartet, dass der UI-Status einer Aktivität während einer Konfigurationsänderung, z. B. Drehung oder Wechsel in den Mehrfenstermodus. Das System zerstört die Aktivität jedoch standardmäßig, wenn eine solche Konfiguration Änderung auftritt, wodurch alle in der Activity-Instanz gespeicherten UI-Status gelöscht werden.

Ebenso erwarten Nutzende, dass der UI-Status gleich bleibt, wenn sie vorübergehend wechseln Sie von Ihrer App zu einer anderen und kehren dann zu dieser zurück. . Das System kann jedoch Ihren Anwendungsprozess zerstören, während der Der Nutzer ist abwesend und deine Aktivität wird beendet.

Wenn Systemeinschränkungen die Aktivität zerstören, behalten Sie die vorübergehenden UI-Status des Nutzers mit einer Kombination aus ViewModel, <ph type="x-smartling-placeholder"></ph> onSaveInstanceState() und/oder lokaler Speicher. Um mehr über die Erwartungen der Nutzenden im Vergleich zum System zu erfahren und wie Sie komplexe UI-Zustandsdaten in vom System initiierte Aktivität und Prozessbeendigung, siehe UI-Status speichern.

In diesem Abschnitt wird der Instanzstatus beschrieben und es wird beschrieben, wie der Instanzstatus onSaveInstance()-Methode, die ein Callback für die Aktivität selbst ist. Wenn Ihr UI-Daten sind schlanker. Sie können nur onSaveInstance() verwenden, um die UI dauerhaft zu speichern. sowohl bei Konfigurationsänderungen als auch bei vom System initiierten Prozessen. Da für onSaveInstance() jedoch Serialisierungs-/Deserialisierungskosten anfallen, In den meisten Fällen verwenden Sie sowohl ViewModel als auch onSaveInstance(), beschrieben in UI-Status speichern

Hinweis : Weitere Informationen zu Konfigurationsänderungen und zum Einschränken von Aktivitäten und wie Sie auf diese Konfigurationsänderungen Sehen Sie sich das System und Jetpack Compose an, Seite Konfigurationsänderungen verarbeiten

Instanzstatus

Es gibt einige Szenarien, in denen Ihre Aktivität aufgrund einer normalen App gelöscht wird z. B. wenn der Nutzer die Zurück-Taste drückt oder Ihre Aktivität signalisiert seine eigene Zerstörung, indem finish() .

Wenn Ihre Aktivität gelöscht wird, weil der Nutzer auf „Zurück“ klickt. oder die Aktivität selbst beendet, sowohl das System- als auch das Nutzungskonzept von Diese Activity-Instanz ist unwiderruflich gelöscht. In diesen entspricht die Erwartung des Nutzers dem Systemverhalten und Sie zusätzliche Arbeit zu erledigen.

Wenn das System die Aktivität jedoch aufgrund von Systemeinschränkungen (z. B. eine Konfigurationsänderung oder eine Speicherauslastung), Activity nicht mehr vorhanden ist, merkt sich das System, dass sie existiert. Wenn Nutzende versuchen, wenn Sie zur Aktivität zurückkehren, erstellt das System eine neue Instanz, Aktivität mit einer Reihe gespeicherter Daten, die den Status der Aktivität beschreiben als es zerstört wurde.

Die gespeicherten Daten, mit denen das System Der vorherige Status wird als Instanzstatus bezeichnet. Es ist eine Sammlung von Schlüssel/Wert-Paare, die in einem Bundle-Objekt gespeichert sind. Standardmäßig enthält der Parameter Das System verwendet zum Speichern von Informationen den Instanzstatus Bundle zu den einzelnen View-Objekten in Ihrem Aktivitätslayout, z. B. Textwert, der in eine EditText-Widget.

Wenn also Ihre Activity-Instanz gelöscht und neu erstellt wurde, ist der Status des Layouts Der vorherige Zustand wurde wiederhergestellt, ohne dass Sie einen Code benötigen. Ihre möglicherweise weitere Statusinformationen, die Sie wiederherstellen möchten, Mitgliedsvariablen, die den Fortschritt der Nutzenden in der Aktivität verfolgen.

Hinweis : Damit das Android-System den Status für die Datenansichten in Ihrer Aktivität nicht erforderlich ist, muss jede Datenansicht eine eindeutige ID haben, die von android:id-Attribut.

Ein Bundle-Objekt eignet sich nicht, um mehr als ein eine geringe Datenmenge, da eine Serialisierung im Hauptthread erforderlich ist und Systemprozessspeicher. Um mehr als eine kleine Datenmenge zu bewahren, verfolgen einen kombinierten Ansatz zur Beibehaltung von Daten mit persistenten lokalen Speicher, die Methode onSaveInstanceState() und die ViewModel-Klasse, wie unter beschrieben UI-Status speichern

Einfachen UI-Status mit onSaveInstanceState() speichern

Sobald Ihre Aktivität endet, ruft das System die onSaveInstanceState() damit Ihre Aktivität Zustandsinformationen in einem Instanzstatus speichern kann, Set. Mit der Standardimplementierung dieser Methode werden Informationen zum Status der Ansichtshierarchie der Aktivität, z. B. in einem EditText-Widget oder die Scrollposition eines ListView-Widget.

Wenn Sie zusätzliche Informationen zum Instanzstatus für Ihre Aktivität speichern möchten, überschreiben Sie onSaveInstanceState() Fügen Sie dem gespeicherten Bundle-Objekt Schlüssel/Wert-Paare hinzu. falls Ihre Aktivität unerwartet vernichtet wird. Beim Überschreiben onSaveInstanceState(), Sie müssen die Implementierung der Basisklasse aufrufen. wenn Sie möchten, dass die Standardimplementierung den Status der Ansichtshierarchie speichern soll. Dies wird im folgenden Beispiel gezeigt:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {
    // Save the user's current game state.
    outState?.run {
        putInt(STATE_SCORE, currentScore)
        putInt(STATE_LEVEL, currentLevel)
    }

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(outState)
}

companion object {
    val STATE_SCORE = "playerScore"
    val STATE_LEVEL = "playerLevel"
}

Java

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state.
    savedInstanceState.putInt(STATE_SCORE, currentScore);
    savedInstanceState.putInt(STATE_LEVEL, currentLevel);

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(savedInstanceState);
}

Hinweis: onSaveInstanceState() ist nicht aufgerufen, wenn der Nutzer die Aktivität explizit schließt, oder in anderen Fällen, in denen finish() wird aufgerufen.

Um persistente Daten wie Nutzereinstellungen oder Daten für eine Datenbank zu speichern, angemessene Gelegenheiten ergreifen, wenn Ihre Aktivität im Vordergrund ausgeführt wird. Wenn sich eine solche Gelegenheit nicht bietet, speichern Sie persistente Daten während der onStop()-Methode.

UI-Status der Aktivität mit gespeichertem Instanzstatus wiederherstellen

Wenn Ihre Aktivität nach dem Löschen neu erstellt wird, kann den gespeicherten Instanzstatus aus dem Bundle wiederherstellen, zu Ihrer Aktivität übergibt. Sowohl die onCreate() und <ph type="x-smartling-placeholder"></ph> onRestoreInstanceState() Callback-Methoden empfangen denselben Bundle, der den Parameter Statusinformationen der Instanz.

Da die Methode onCreate() aufgerufen, ob das System eine neue Instanz Ihrer Aktivität erstellt oder einen vorherigen neu erstellen, müssen Sie prüfen, ob der Status Bundle ist null, bevor Sie versuchen, sie zu lesen. Wenn der Wert null ist, erstellt eine neue Instanz der Aktivität, anstatt eine die zuvor zerstört wurde.

Das folgende Code-Snippet zeigt, wie Sie einige Statusdaten in onCreate():

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState) // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        with(savedInstanceState) {
            // Restore value of members from saved state.
            currentScore = getInt(STATE_SCORE)
            currentLevel = getInt(STATE_LEVEL)
        }
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        // Restore value of members from saved state.
        currentScore = savedInstanceState.getInt(STATE_SCORE);
        currentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

Anstatt den Status während einer onCreate(), können Sie onRestoreInstanceState(), den das System nach dem onStart()-Methode. Das System ruft auf, onRestoreInstanceState() wenn ein gespeicherter Status wiederhergestellt werden kann. müssen nicht prüfen, ob Bundle null ist.

Kotlin

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState)

    // Restore state members from saved instance.
    savedInstanceState?.run {
        currentScore = getInt(STATE_SCORE)
        currentLevel = getInt(STATE_LEVEL)
    }
}

Java

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance.
    currentScore = savedInstanceState.getInt(STATE_SCORE);
    currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

Achtung: Rufen Sie immer die Implementierung der übergeordneten Klasse von onRestoreInstanceState() damit die Standardimplementierung den Status der Ansichtshierarchie wiederherstellen kann.

Zwischen Aktivitäten wechseln

Es ist wahrscheinlich, dass eine App eine Aktivität startet und beendet – möglicherweise mehrmals während der Lebensdauer der App, z. B. wenn der Nutzer auf die Schaltfläche „Zurück“ des Geräts tippt oder eine andere Aktivität gestartet wird.

Dieser Abschnitt behandelt Themen, die Sie kennen müssen, um eine erfolgreiche Aktivitätsumstellung zu implementieren. Dazu gehören das Starten von Aktivitäten aus einer anderen Aktivität, das Speichern von Aktivitäten und den Aktivitätsstatus wiederherstellen.

Eine Aktivität über eine andere starten

Eine Aktivität muss oft irgendwann mit einer anderen Aktivität beginnen. Diese Anforderung tritt beispielsweise auf, wenn eine App vom aktuellen Bildschirm zu einem neuen.

Je nachdem, ob Ihre Aktivität ein Ergebnis der neuen Aktivität zurückgeben möchte gleich beginnen soll, starten Sie die neue Aktivität mit dem startActivity() oder die Methode startActivityForResult() . In beiden Fällen übergeben Sie ein Intent-Objekt.

Das Objekt Intent gibt entweder die genaue Aktivität, die Sie starten möchten, oder beschreibt die Art der Aktion, die Sie durchführen möchten. Das System wählt die passende Aktivität für Sie aus, die sogar aus einer anderen Anwendung. Ein Intent-Objekt kann kleine Datenmengen, die von der gestarteten Aktivität verwendet werden. Weitere Informationen zur Klasse Intent finden Sie unter Absichten und Absichten Filter.

startActivity()

Wenn die neu gestartete Aktivität kein Ergebnis zurückgeben muss, kann sie mit der aktuellen Aktivität gestartet werden indem Sie die Methode startActivity() .

Wenn Sie innerhalb Ihrer eigenen Anwendung arbeiten, müssen Sie häufig einfach eine bekannte Aktivität starten. Das folgende Code-Snippet zeigt beispielsweise, wie eine Aktivität namens SignInActivity

Kotlin

val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)

Java

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

Möglicherweise möchte Ihre Anwendung auch bestimmte Aktionen ausführen, z. B. eine E-Mail senden, oder eine Statusaktualisierung, die auf Daten aus deinen Aktivitäten basiert. In diesem Fall verfügt Ihre Anwendung möglicherweise nicht über eigene Aktivitäten zum Ausführen solcher Aktionen. So können Sie die Aktivitäten anderer Apps auf dem Gerät nutzen, die Aktionen für Sie ausführen kann.

Hier sind Intents sehr wertvoll. Sie können eine die eine auszuführende Aktion beschreibt, und das System startet die entsprechende Aktivitäten aus einer anderen Anwendung. Wenn es mehrere Aktivitäten gibt, die den Intent verarbeiten können, kann der Nutzer auswählen, welche verwendet werden soll. Wenn Sie z. B. zulassen möchten, dass der Nutzer eine können Sie den folgenden Intent erstellen:

Kotlin

val intent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)

Java

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

Das zusätzliche EXTRA_EMAIL, das dem Intent hinzugefügt wird, ist ein String-Array von E-Mail-Adressen, an die die E-Mail gesendet werden soll. Wenn eine E-Mail-Anwendung auf diesen Intent antwortet, liest er das String-Array aus den zusätzlichen und platziert die Adressen in „nach“ des Formulars zum Verfassen von E-Mails. In dieser wird die Aktivität der E-Mail-Anwendung gestartet. Wenn der Nutzer fertig ist, Ihre Aktivität fortgesetzt wird.

startActivityForResult()

Manchmal möchten Sie nach dem Ende einer Aktivität ein Ergebnis zurückerhalten. Sie könnten zum Beispiel Eine Aktivität, bei der der Nutzer eine Person aus einer Liste von Kontakten auswählen kann. Wenn er endet, wird die Person, die ausgewählt wurde. Dazu rufen Sie die Methode startActivityForResult(Intent, int) -Methode, wobei der Ganzzahlparameter den Aufruf identifiziert.

Diese Kennung dient dazu, zwischen mehreren Aufrufen von startActivityForResult(Intent, int) aus derselben Aktivität. Es ist keine globale Kennung Außerdem besteht die Gefahr, dass sie nicht mit anderen Apps oder Aktivitäten in Konflikt stehen. Das Ergebnis wird über die onActivityResult(int, int, Intent) .

Wenn eine Kinderaktivität beendet wird, kann sie setResult(int) aufrufen, um Daten an das übergeordnete Element zurückgeben. Die untergeordnete Aktivität muss einen Ergebniscode bereitstellen. Dies kann die Standardergebnisse sein. RESULT_CANCELED, RESULT_OK oder ein beliebiger benutzerdefinierter Wert ab RESULT_FIRST_USER.

Außerdem kann die untergeordnete Aktivität optional ein Intent zurückgeben. -Objekt, das zusätzliche gewünschte Daten enthält. Die übergeordnete Aktivität verwendet die onActivityResult(int, int, Intent) zusammen mit dem ganzzahligen Kennzeichner der ursprünglichen Aktivität um die Informationen zu erhalten.

Wenn die Aktivität eines untergeordneten Elements fehlschlägt, z. B. durch einen Absturz, wird das übergeordnete Element activity erhält ein Ergebnis mit dem Code RESULT_CANCELED.

Kotlin

class MyActivity : Activity() {
    // ...

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // When the user center presses, let them pick a contact.
            startActivityForResult(
                    Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),
                    PICK_CONTACT_REQUEST)
            return true
        }
        return false
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        when (requestCode) {
            PICK_CONTACT_REQUEST ->
                if (resultCode == RESULT_OK) {
                    // A contact was picked. Display it to the user.
                    startActivity(Intent(Intent.ACTION_VIEW, intent?.data))
                }
        }
    }

    companion object {
        internal val PICK_CONTACT_REQUEST = 0
    }
}

Java

public class MyActivity extends Activity {
     // ...

     static final int PICK_CONTACT_REQUEST = 0;

     public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             // When the user center presses, let them pick a contact.
             startActivityForResult(
                 new Intent(Intent.ACTION_PICK,
                 new Uri("content://contacts")),
                 PICK_CONTACT_REQUEST);
            return true;
         }
         return false;
     }

     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PICK_CONTACT_REQUEST) {
             if (resultCode == RESULT_OK) {
                 // A contact was picked. Display it to the user.
                 startActivity(new Intent(Intent.ACTION_VIEW, data));
             }
         }
     }
 }

Aktivitäten koordinieren

Wenn mit einer Aktivität eine andere beginnt, erleben beide Lebenszyklusübergänge. Die erste Aktivität wird beendet und wechselt in den Status „Pausiert“ oder „Angehalten“, während die andere erstellt wird. Falls diese Aktivitäten Daten weitergeben, die auf einem Datenträger oder an anderer Stelle gespeichert sind, Es ist wichtig zu verstehen, dass die erste Aktivität nicht vor der zweiten vollständig gestoppt wird. erstellt wird. Vielmehr überschneidet sich der Start des zweiten mit dem Prozess der um die erste zu stoppen.

Die Reihenfolge der Lebenszyklus-Callbacks ist klar definiert, insbesondere wenn die beiden Aktivitäten im selben Prozess – mit anderen Worten, in der gleichen App – und die eine startet die andere. Hier ist die Reihenfolge der Vorgänge, wenn Aktivität A mit Aktivität B beginnt:

  1. Die Methode onPause() von Aktivität A wird ausgeführt.
  2. onCreate() von Aktivität B onStart() und onResume()-Methoden werden nacheinander ausgeführt. Aktivität B liegt jetzt im Fokus des Nutzers.
  3. Ist Aktivität A nicht mehr auf dem Bildschirm sichtbar, wird die Methode onStop() ausgeführt.

Mit dieser Abfolge von Lebenszyklus-Callbacks können Sie den Übergang von einer Aktivität zur anderen.