Umgang mit Konfigurationsänderungen

Einige Gerätekonfigurationen können sich ändern, während die App ausgeführt wird. Dazu gehören: sind jedoch nicht auf Folgendes beschränkt:

  • Anzeigegröße der App
  • Bildschirmausrichtung
  • Schriftgröße und -stärke
  • Sprache
  • Dunkler und heller Modus im Vergleich
  • Tastaturverfügbarkeit

Die meisten dieser Konfigurationsänderungen sind auf Nutzerinteraktionen zurückzuführen. Für Zum Beispiel ändert sich durch Drehen oder Zusammenklappen des Geräts der Platz auf dem Bildschirm. für Ihre App verfügbar. Wenn Sie Geräteeinstellungen wie Schriftgröße ändern, Sprache oder bevorzugtes Design die entsprechenden Werte in der Configuration-Objekt.

Diese Parameter erfordern in der Regel ausreichend große Änderungen an der Benutzeroberfläche Ihrer Anwendung dass die Android-Plattform über einen speziellen Mechanismus verfügt, wenn sie sich ändern. Dieser Mechanismus ist die Neuerstellung von Activity.

Freizeitaktivitäten

Das System erstellt ein Activity neu, wenn eine Konfigurationsänderung erfolgt. Dazu muss das System onDestroy() aufruft und die vorhandene Activity-Instanz löscht. Dann erstellt mit onCreate() eine neue Instanz. Die neue Activity-Instanz ist mit der neuen, aktualisierten Konfiguration initialisiert. Das bedeutet auch, dass das System erstellt mit der neuen Konfiguration auch die Benutzeroberfläche neu.

Durch die Neuerstellung kann sich Ihre Anwendung an neue Konfigurationen anpassen, indem Ihre Anwendung wird automatisch mit alternativen Ressourcen um die neue Gerätekonfiguration aufzurufen.

Beispiel für Freizeit

Hier ein Beispiel: TextView, das einen statischen Titel mit android:text="@string/title", wie in einer Layout-XML-Datei definiert. Wenn die Ansicht erstellt wird, wird der Text genau einmal basierend auf der aktuellen Sprache festgelegt. Wenn die ändert das System die Aktivität. Folglich weist das System erstellt auch die Ansicht neu und initialisiert sie mit dem richtigen Wert basierend Sprache.

Bei der Wiederherstellung werden auch alle Status gelöscht, die als Felder in der Activity oder in einem der enthaltenen Fragment-, View- oder anderen Objekte. Dieses liegt daran, dass die Activity-Neuerstellung eine völlig neue Instanz von Activity erstellt. und die Benutzeroberfläche. Außerdem ist die alte Activity nicht mehr sichtbar oder gültig. verbleibende Verweise auf sie oder die enthaltenen Objekte sind veraltet. Sie können dazu führen, Bugs, Speicherlecks und Abstürzen.

.

Erwartungen der Nutzenden

Der Nutzer einer Anwendung erwartet, dass der Status beibehalten wird. Wenn Nutzende ein Formular ausfüllen und öffnet eine andere App im Mehrfenstermodus, um auf Informationen zu verweisen, eine schlechte User Experience darstellt, wenn sie zu einem klaren Formular zurückkehren oder eine an einer anderen Stelle in der App. Als Entwickler musst du für eine einheitliche Nutzererfahrung sorgen durch Konfigurationsänderungen und die Neuerstellung von Aktivitäten.

So können Sie prüfen, ob der Status in Ihrer Anwendung beibehalten wird: Aktionen, die zu Konfigurationsänderungen führen, sowohl während die App im Vordergrund ausgeführt während es im Hintergrund läuft. Diese Aktivitäten umfassen:

  • Drehen des Geräts
  • Mehrfenstermodus wird aktiviert
  • Größe der Anwendung im Mehrfenstermodus oder in einem Freiformfenster anpassen
  • Faltbares Gerät mit mehreren Displays
  • Systemdesign ändern, z. B. dunkler oder heller Modus
  • Schriftgröße ändern
  • System- oder App-Sprache ändern
  • Hardwaretastatur verbinden oder trennen
  • Dock verbinden oder trennen

Es gibt drei primäre Ansätze, mit denen Sie den relevanten Status durch Activity-Neuerstellung. Welche Methode Sie verwenden sollten, hängt von der Art des Status ab, den Sie verwenden möchten. beibehalten:

  • Lokale Persistenz für den Umgang mit Prozessbeendigung bei komplexen oder großen Daten. Der nichtflüchtige lokale Speicher umfasst Datenbanken oder DataStore.
  • Beibehaltene Objekte wie ViewModel-Instanzen zur Verarbeitung des UI-bezogenen Status in während der Nutzer die App aktiv nutzt.
  • Gespeicherter Instanzstatus, um das Beenden des vom System initiierten Prozesses zu verarbeiten und Übergangszustand, der von Nutzereingabe oder -navigation abhängt.

Ausführliche Informationen zu den jeweiligen APIs Wenn Sie beide verwenden, lesen Sie UI-Status speichern.

Freizeitaktivitäten einschränken

Sie können die automatische Wiederherstellung von Aktivitäten bei bestimmten Konfigurationsänderungen verhindern. Bei der Neuerstellung von Activity werden die gesamte UI und alle abgeleiteten Objekte neu erstellt von Activity. Es gibt gute Gründe, dies zu vermeiden. Für Beispiel: Ihre Anwendung muss während eines bestimmten Zeitraums oder die Leistung beeinträchtigt ist. In diesem Fall können Sie deklarieren, dass Ihre Aktivität die Konfigurationsänderung selbst verarbeitet, und verhindert, dass das System Ihre Aktivitäten neu startet.

So deaktivieren Sie die Wiederherstellung von Aktivitäten für bestimmte Konfigurationsänderungen: fügen Sie den Konfigurationstyp android:configChanges im <activity>-Eintrag in Ihrer AndroidManifest.xml-Datei. Mögliche Werte werden in der Dokumentation für das Attribut android:configChanges

Der folgende Manifestcode deaktiviert die Neuerstellung von Activity für MyActivity in folgenden Fällen: Bildschirmausrichtung und Tastaturverfügbarkeit ändern:

<activity
    android:name=".MyActivity"
    android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
    android:label="@string/app_name">

Einige Konfigurationsänderungen führen immer dazu, dass die Aktivität neu gestartet wird. Kann nicht deaktiviert werden . Beispielsweise kann die dynamische Farbänderung nicht deaktiviert werden. in Android 12L (API-Level 32) eingeführt.

Auf Konfigurationsänderungen im Ansichtssystem reagieren

Wenn im View-System eine Konfigurationsänderung auftritt, für die Sie deaktivierte Neuerstellung von Activity, die Aktivität empfängt einen Anruf an Activity.onConfigurationChanged() Alle angehängten Ansichten erhalten auch ein Aufruf von View.onConfigurationChanged(). Bei Konfigurationsänderungen nicht zu android:configChanges hinzugefügt haben, erstellt das System die Aktivität neu wie gewohnt.

Die Callback-Methode onConfigurationChanged() empfängt ein Objekt Configuration, das die neue Gerätekonfiguration angibt. Gelesen die Felder im Configuration-Objekt, um zu bestimmen, was Ihr neues Konfiguration ist. Aktualisieren Sie die Ressourcen, um die nachfolgenden Änderungen vorzunehmen die Sie in Ihrer Benutzeroberfläche verwenden. Wenn das System diese Methode aufruft, Das Resources-Objekt wurde aktualisiert, um Ressourcen basierend auf dem neuen Konfiguration. So können Sie Elemente Ihrer Benutzeroberfläche zurücksetzen, ohne deine Aktivität neu zu starten.

Die folgende onConfigurationChanged()-Implementierung prüft beispielsweise Ob eine Tastatur verfügbar ist:

Kotlin

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)

    // Checks whether a keyboard is available
    if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show()
    } else if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_NO) {
        Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show()
    }
}

Java

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks whether a keyboard is available
    if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show();
    } else if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO){
        Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show();
    }
}

Wenn Sie Ihre Anwendung auf Grundlage dieser Konfiguration nicht aktualisieren müssen können Sie onConfigurationChanged() stattdessen nicht implementieren. Dabei werden weiterhin alle Ressourcen genutzt, die vor der Konfigurationsänderung genutzt wurden, und Sie haben nur einen Neustart Ihrer Aktivität vermieden. Beispiel: Eine TV-App möchten möglicherweise nicht reagieren, wenn eine Bluetooth-Tastatur angeschlossen oder getrennt ist.

Beibehaltungsstatus

Wenn Sie diese Technik verwenden, müssen Sie den Zustand während der normalen Aktivitätslebenszyklus. Das hat folgende Gründe:

  • Unvermeidliche Änderungen:Konfigurationsänderungen, die Sie nicht verhindern können, Anwendung neu starten.
  • Prozessabschluss: Ihre Anwendung muss in der Lage sein, vom System initiierte Prozessbeendigung. Verlässt der Nutzer die Anwendung und ruft sie die Hintergrund ausführen, könnte das System die App zerstören.

In Jetpack Compose auf Konfigurationsänderungen reagieren

Mit Jetpack Compose kann Ihre App einfacher auf Konfigurationsänderungen reagieren. Wenn Sie jedoch die Wiederherstellung von Activity für alle Konfigurationsänderungen deaktivieren, muss Ihre App trotzdem korrekt verarbeiten, Konfigurationsänderungen.

Das Objekt Configuration ist in der Hierarchie „Compose UI“ mit folgendem Befehl verfügbar: lokale LocalConfiguration-Komposition Wenn sich etwas ändert, zusammensetzbare Funktionen, die aus LocalConfiguration.current lesen, neu zusammensetzen. Für Informationen zur Funktionsweise lokaler Kompositionen mit CompositionLocal.

Beispiel

Im folgenden Beispiel zeigt eine zusammensetzbare Funktion ein Datum in einem bestimmten Format an. Die zusammensetzbare Funktion reagiert auf Änderungen der Sprachkonfiguration des Systems mit folgendem Aufruf: ConfigurationCompat.getLocales() mit LocalConfiguration.current.

@Composable
fun DateText(year: Int, dayOfYear: Int) {
    val dateTimeFormatter = DateTimeFormatter.ofPattern(
        "MMM dd",
        ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
    )
    Text(
        dateTimeFormatter.format(LocalDate.ofYearDay(year, dayOfYear))
    )
}

Um zu vermeiden, dass Activity neu erstellt wird, wenn sich das Gebietsschema ändert, wird die Activity, die den Beim Erstellen von Code müssen Änderungen der Sprachkonfiguration deaktiviert werden. Dazu müssen Sie Legen Sie android:configChanges auf locale|layoutDirection fest.

Konfigurationsänderungen: Schlüsselkonzepte und Best Practices

Dies sind die wichtigsten Konzepte, die Sie bei der Arbeit an der Konfiguration Änderungen:

  • Konfigurationen: Gerätekonfigurationen legen fest, wie die Benutzeroberfläche für z. B. die Anzeigegröße der App, die Sprache oder das Systemdesign.
  • Konfigurationsänderungen:Konfigurationen ändern sich durch Nutzerinteraktionen. Für Beispielsweise kann der Nutzer die Geräteeinstellungen ändern oder seine physische Interaktion ändern. mit dem Gerät. Das lässt sich nicht verhindern, Konfigurationsänderungen.
  • Neuerstellung von Activity: Konfigurationsänderungen führen zur Neuerstellung von Activity. ist standardmäßig aktiviert. Dies ist ein integrierter Mechanismus zur Neuinitialisierung des App-Status für die neue Konfiguration.
  • Zerstörung von Activity: Durch die Wiederherstellung von Activity zerstört das System Folgendes: alte Activity-Instanz und erstellen Sie stattdessen eine neue. Die alte Instanz ist oder obsolet geworden. Alle verbleibenden Verweise darauf führen zu Speicherlecks, Bugs oder Abstürze.
  • State: Status in der alten Activity-Instanz ist in der neuen nicht vorhanden. Activity-Instanz, da es sich um zwei verschiedene Objektinstanzen handelt. Beibehalten der App und des Nutzerstatus, wie unter UI-Status speichern beschrieben.
  • Deaktivieren:Die Wiederherstellung von Aktivitäten wird für einen Konfigurationstyp deaktiviert. ist eine potenzielle Optimierung. Es erfordert, dass Ihre App als Reaktion auf die neue Konfiguration korrekt aktualisiert wird.

Beachten Sie die folgenden Best Practices, um für eine positive Nutzererfahrung zu sorgen:

  • Auf häufige Konfigurationsänderungen vorbereitet sein: Gehen Sie nicht davon aus, dass Konfigurationsänderungen selten oder nie passieren, unabhängig vom API-Level, dem Formfaktor oder dem UI-Toolkit. Wenn ein Nutzer eine Konfigurationsänderung vornimmt, erwartet er, dass Apps aktualisiert und auch mit der neuen Konfiguration weiter einwandfrei funktionieren.
  • Status beibehalten: Der Status des Nutzers bleibt beim Neuerstellen von Activity erhalten. erfolgt. Behalten Sie den Status wie unter UI-Status speichern beschrieben bei.
  • Schnelle Lösung deaktivieren: Deaktivieren Sie nicht die Wiederherstellung von Activity. um Zustandsverlust zu vermeiden. Die Deaktivierung von Freizeitaktivitäten erfordert das Versprechen eines Umgangs mit der Änderung erfüllen, und Sie können trotzdem das Status aufgrund der Wiederherstellung von Activity aus anderen Konfigurationsänderungen, Prozess Tod oder Schließen der App. Activity kann nicht vollständig deaktiviert werden. Freizeitaktivitäten. Behalten Sie den Status wie unter UI-Status speichern beschrieben bei.
  • Vermeiden Sie keine Konfigurationsänderungen:Schränken Sie die Ausrichtung nicht ein, das Seitenverhältnis oder die Größe, um Konfigurationsänderungen zu vermeiden, Activity-Neuerstellung. Dies wirkt sich negativ auf Nutzer aus, die deine App ihre bevorzugte Art und Weise geschieht.

Größenbasierte Konfigurationsänderungen verarbeiten

Größenbasierte Konfigurationsänderungen können jederzeit erfolgen und sind mit größerer Wahrscheinlichkeit wenn Ihre App auf einem Gerät mit großem Bildschirm ausgeführt wird, Mehrfenstermodus aktivieren. Sie erwarten, dass Ihre App in diesen Bereichen zu verbessern.

Es gibt zwei allgemeine Arten von Größenänderungen: signifikante und unbedeutend sein. Eine erhebliche Größenänderung liegt vor, alternative Ressourcen für die neue Konfiguration gelten. Grund dafür ist eine Abweichung bei Bildschirmgröße wie Breite, Höhe oder kleinste Breite. Zu diesen Ressourcen gehören die von der App selbst und die aus einer ihrer Bibliotheken definiert sind.

Neuerstellung von Aktivitäten für größenbasierte Konfigurationsänderungen einschränken

Wenn Sie die Neuerstellung von Activity für größenbasierte Konfigurationsänderungen deaktivieren, erstellt das System Activity nicht neu. Stattdessen erhält sie einen Anruf Activity.onConfigurationChanged() Alle angehängten Ansichten empfangen einen Aufruf an View.onConfigurationChanged()

Die Wiederherstellung von Activity ist für größenbasierte Konfigurationsänderungen deaktiviert, wenn du hast „android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout“ in Ihrer Manifest-Datei.

Neuerstellung von Aktivitäten für größenbasierte Konfigurationsänderungen zulassen

Unter Android 7.0 (API-Level 24) und höher erfolgt die Neuerstellung von Activity nur für größenbasierte Konfigurationsänderungen, wenn die Größenänderung erheblich ist. Wenn das System keine Activity aufgrund unzureichender Größe neu erstellen kann, ruft das System möglicherweise Activity.onConfigurationChanged() und View.onConfigurationChanged().

In Bezug auf Activity und View sind einige Einschränkungen zu beachten. Callbacks, wenn das Activity nicht neu erstellt wird:

  • Auf Android 11 (API-Level 30) bis Android 13 (API-Level 33) Activity.onConfigurationChanged() wird nicht angerufen.
  • Es gibt ein bekanntes Problem, bei dem View.onConfigurationChanged() möglicherweise nicht unter Android 12L (API-Level 32) und in frühen Versionen von Android 13 (API-Level 33) Weitere Informationen finden Sie in diesem öffentlichen Problem. Dieses Problem wurde in den späteren Versionen von Android 13 und Android 14 behoben.

Für Code, für den eine größenbasierte Konfiguration überwacht werden muss Änderungen vornehmen, empfehlen wir die Verwendung eines Dienstprogramms View mit einem überschriebenen View.onConfigurationChanged() anstelle von Activity-Neuerstellungen oder Activity.onConfigurationChanged().