Gestire le modifiche alla configurazione

Alcune configurazioni del dispositivo possono cambiare mentre l'app è in esecuzione. Questi includono: senza limitazioni:

  • Dimensioni di visualizzazione dell'app
  • Orientamento schermo
  • Dimensioni e spessore del carattere
  • Impostazioni internazionali
  • Modalità Buio e modalità Luce
  • Disponibilità della tastiera

La maggior parte di queste modifiche alla configurazione avviene a causa di alcune interazioni dell'utente. Per Ad esempio, ruotando o piegando il dispositivo si modifica la quantità di spazio sullo schermo disponibili per la tua app. Analogamente, l'alterazione delle impostazioni del dispositivo, come le dimensioni dei caratteri, lingua o tema preferito cambiano i rispettivi valori nel Configuration.

Questi parametri richiedono in genere modifiche abbastanza significative all'interfaccia utente dell'applicazione che la piattaforma Android disponga di un meccanismo appositamente progettato per quando cambiano. Questo meccanismo è ricreazione di Activity.

Attività ricreative

Il sistema ricrea un Activity quando si verifica una modifica alla configurazione. Per fare ciò, il sistema chiama onDestroy() ed elimina l'istanza Activity esistente. Poi crea una nuova istanza utilizzando onCreate() e la nuova istanza Activity viene inizializzata con la nuova configurazione aggiornata. Ciò significa anche che il sistema ricrea la UI con la nuova configurazione.

Il comportamento della nuova creazione aiuta l'applicazione ad adattarsi alle nuove configurazioni ricaricando automaticamente l'applicazione con risorse alternative corrispondenti la nuova configurazione del dispositivo.

Esempio per attività ricreative

Considera un TextView che mostra un titolo statico utilizzando android:text="@string/title", come definito in un file XML di layout. Quando la vista viene creato, imposta il testo esattamente una volta, in base alla lingua corrente. Se le modifiche alla lingua, il sistema ricrea l'attività. Di conseguenza, il sistema ricrea la vista e la inizializza al valore corretto in base al nuovo lingua.

La ricreazione cancella anche qualsiasi stato mantenuto come campi nella Activity o in uno qualsiasi dei suoi oggetti Fragment, View o altri contenuti. Questo è che la ricreazione di Activity crea un'istanza completamente nuova dell'elemento Activity e la UI. Inoltre, la versione precedente di Activity non è più visibile o valida, pertanto qualsiasi i riferimenti rimanenti o agli oggetti che contiene sono obsoleti. Possono causare bug, fughe di memoria e arresti anomali.

Aspettative degli utenti

L'utente di un'app si aspetta che lo stato venga mantenuto. Se un utente compila un modulo e apre un'altra app in modalità multi-finestra per fare riferimento alle informazioni, è un'esperienza negativa per gli utenti che tornano in un modulo cancellato o in un'altra posizione completa dell'app. In qualità di sviluppatore, devi fornire un'esperienza utente coerente attraverso modifiche alla configurazione e ricreazione delle attività.

Per verificare se lo stato viene conservato nell'applicazione, puoi eseguire azioni che causano modifiche alla configurazione sia quando l'app è in primo piano sia mentre è in background. Queste azioni includono:

  • Rotazione del dispositivo
  • Attivazione della modalità multi-finestra
  • Ridimensionamento dell'applicazione in modalità multi-finestra o in una finestra in formato libero
  • Come piegare un dispositivo pieghevole con più display
  • Modifica del tema del sistema, ad esempio modalità Buio rispetto a modalità Luce
  • Modifica delle dimensioni dei caratteri
  • Modifica della lingua di sistema o dell'app
  • Collegare o scollegare una tastiera hardware
  • Collegare o scollegare una base di ricarica

Esistono tre approcci principali che puoi adottare per preservare lo stato pertinente Ricreazione di Activity. Le opzioni da utilizzare dipendono dal tipo di stato che vuoi conserva:

  • Persistenza locale per gestire la morte del processo per dati complessi o di grandi dimensioni. L'archiviazione locale permanente include database o DataStore.
  • Oggetti conservati, come le istanze di ViewModel, per gestire lo stato relativo all'interfaccia utente in mentre l'utente usa attivamente l'app.
  • Stato dell'istanza salvata per gestire la fine del processo avviato dal sistema e mantenere stato temporaneo che dipende dall'input o dalla navigazione dell'utente.

Per ulteriori informazioni sulle API per ciascun tipo, e l'utilizzo di ciascun stato è appropriato, consulta l'articolo Salvare gli stati della UI.

Limita attività ricreative

Puoi impedire la ricreazione automatica delle attività per determinate modifiche alla configurazione. La ricreazione di Activity comporta la ricreazione dell'intera UI e di tutti gli oggetti derivati da Activity. Potresti avere buoni motivi per evitare questa situazione. Per Ad esempio, la tua app potrebbe non dover aggiornare le risorse durante configurazione o la limitazione delle prestazioni. In questo caso, puoi dichiarare che la tua attività gestisce personalmente la modifica alla configurazione impedire al sistema di riavviare la tua attività.

Per disattivare la ricreazione delle attività per determinate modifiche alla configurazione, aggiungi il tipo di configurazione a android:configChanges nel Voce <activity> nel file AndroidManifest.xml. I valori possibili vengono visualizzati nella documentazione per l'attributo android:configChanges.

Il seguente codice manifest disattiva la nuova creazione di Activity per MyActivity quando l'orientamento dello schermo e la disponibilità della tastiera cambiano:

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

Alcune modifiche alla configurazione comportano sempre il riavvio dell'attività. Non puoi disattivare che li rappresentano. Ad esempio, non puoi disattivare la modifica dinamica dei colori. Introdotto in Android 12L (livello API 32).

Reagisci alle modifiche alla configurazione nel sistema di visualizzazione

Nel sistema View, quando si verifica una modifica alla configurazione per cui hai ha disattivato Activity, l'attività riceve una chiamata a Activity.onConfigurationChanged() Anche le viste allegate ricevono un chiamata a View.onConfigurationChanged(). Per le modifiche alla configurazione non sono stati aggiunti a android:configChanges, il sistema ricrea l'attività come al solito.

Il metodo di callback onConfigurationChanged() riceve Configuration che specifica la nuova configurazione del dispositivo. Letto campi nell'oggetto Configuration per determinare il nuovo configurazione. Per apportare le modifiche successive, aggiorna le risorse che utilizzi nell'interfaccia. Quando il sistema chiama questo metodo, l'attività L'oggetto Resources viene aggiornato per restituire risorse in base al nuovo configurazione. In questo modo puoi reimpostare gli elementi della UI senza il sistema la tua attività.

Ad esempio, i seguenti controlli di implementazione di onConfigurationChanged() se è disponibile una tastiera:

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();
    }
}

Se non devi aggiornare l'applicazione in base a queste configurazioni modifiche, non puoi implementare onConfigurationChanged(). In questo tutte le risorse usate prima della modifica alla configurazione saranno ancora usate, e hai solo evitato di riavviare la tua attività. Ad esempio, un'app TV potrebbe non voler reagire quando una tastiera Bluetooth viene collegata o scollegata.

Conserva stato

Quando utilizzi questa tecnica, devi mantenere lo stato durante il normale ciclo di vita dell'attività. Ciò è dovuto ai seguenti motivi:

  • Modifiche non evitabili: le modifiche alla configurazione che non puoi impedire possono riavvia l'applicazione.
  • Terminazione del processo: la tua applicazione deve essere in grado di gestire l'avvio dal sistema processo di morte. Se l'utente abbandona l'applicazione e quest'ultima va alla in background, il sistema potrebbe distruggere l'app.

Reagisci alle modifiche alla configurazione in Jetpack Compose

Jetpack Compose consente alla tua app di reagire più facilmente alle modifiche alla configurazione. Tuttavia, se disabiliti la ricreazione di Activity per tutte le modifiche della configurazione in cui si trova possibile, la tua app deve comunque gestire correttamente modifiche alla configurazione.

L'oggetto Configuration è disponibile nella gerarchia dell'interfaccia utente di Compose con la composizione LocalConfiguration locale. Ogni volta che cambia, le funzioni componibili che leggono da LocalConfiguration.current si ricompongono. Per informazioni su come funziona la composizione locale, consulta Con ambito locale con ComposizioneLocal.

Esempio

Nell'esempio seguente, un componibile visualizza una data con un formato specifico. Il componibile reagisce alle modifiche della configurazione delle impostazioni internazionali di sistema richiamando ConfigurationCompat.getLocales() con 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))
    )
}

Per evitare la ricreazione di Activity quando le impostazioni internazionali cambiano, Activity ospita il Il codice di composizione deve disattivare le modifiche alla configurazione delle impostazioni internazionali. Per farlo, imposta android:configChanges su locale|layoutDirection.

Modifiche alla configurazione: concetti chiave e best practice

Questi sono i concetti chiave che devi conoscere quando lavori alla configurazione modifiche:

  • Configurazioni:le configurazioni del dispositivo definiscono la modalità di visualizzazione della UI all'utente, ad esempio dimensioni di visualizzazione dell'app, impostazioni internazionali o tema di sistema.
  • Modifiche alla configurazione:le configurazioni cambiano attraverso l'interazione dell'utente. Per Ad esempio, l'utente potrebbe modificare le impostazioni del dispositivo o il modo in cui interagisce con il dispositivo. Non c'è modo di evitare modifiche alla configurazione.
  • Ricreazione di Activity: le modifiche alla configurazione generano Activity ricreazione per impostazione predefinita. Si tratta di un meccanismo integrato per reinizializzare lo stato dell'app per una nuova configurazione.
  • Eliminazione di Activity: la ricreazione Activity causa l'eliminazione del sistema vecchia istanza Activity e crearne una nuova in sostituzione. La vecchia istanza è ora obsoleta. Eventuali riferimenti rimanenti comportano perdite di memoria, bug o arresti anomali.
  • Stato: lo stato della vecchia istanza Activity non è presente in quella nuova Activity, perché sono due istanze di oggetto diverse. Conserva l'app e lo stato dell'utente come descritto in Salvare gli stati dell'UI.
  • Disattiva:disattivazione della ricreazione delle attività per un tipo di configurazione una modifica è una potenziale ottimizzazione. Richiede che la tua app si aggiorna correttamente in reazione alla nuova configurazione.

Per offrire una buona esperienza utente, osserva le seguenti best practice:

  • Preparati a modifiche frequenti alla configurazione: non dare per scontato che le modifiche alla configurazione siano rari o non si verificano mai, indipendentemente dal livello API, dal fattore di forma o dal toolkit dell'interfaccia utente. Quando un utente provoca una modifica alla configurazione, si aspetta che le app vengano aggiornate e continuano a funzionare correttamente con la nuova configurazione.
  • Conserva stato: non perdere lo stato dell'utente quando Activity ricreazione . Conserva lo stato come descritto in Salvare gli stati della UI.
  • Evita la disattivazione come soluzione rapida: non disattivare la ricreazione di Activity come scorciatoia per evitare la perdita di stato. Per disattivare la ricreazione dell'attività, devi mantenere la promessa di gestire il cambiamento e puoi comunque perdere stato dovuto alla ricreazione di Activity da altre modifiche alla configurazione, processo o la chiusura dell'app. È impossibile disattivare completamente Activity attività ricreative. Conserva lo stato come descritto in Salvare gli stati della UI.
  • Non evitare modifiche alla configurazione: non porre restrizioni sull'orientamento, proporzioni o ridimensionabilità per evitare modifiche alla configurazione Activity ricreazione. Questo ha un impatto negativo sugli utenti che vogliono utilizzare la tua app nei nel modo che preferiscono.

Gestire le modifiche alla configurazione in base alle dimensioni

Le modifiche alla configurazione basate sulle dimensioni possono avvenire in qualsiasi momento e hanno maggiori probabilità Quando l'app viene eseguita su un dispositivo con uno schermo grande su cui gli utenti possono accedere modalità multi-finestra. Si aspettano che la tua app funzioni bene completamente gestito di Google Cloud.

Esistono due tipi generali di variazioni delle dimensioni: significativa e non significativo. Una modifica significativa delle dimensioni si verifica quando un insieme diverso risorse alternative si applicano alla nuova configurazione a causa di una differenza dimensioni dello schermo, ad esempio larghezza, altezza o larghezza minima. Queste risorse includono quelle definite dall'app e quelle di qualsiasi sua libreria.

Limita la ricreazione delle attività per le modifiche alla configurazione in base alle dimensioni

Quando disattivi la ricreazione di Activity per le modifiche alla configurazione basata sulle dimensioni, non ricrea l'elemento Activity. Riceve invece una chiamata Activity.onConfigurationChanged() Le visualizzazioni allegate ricevono una chiamata a View.onConfigurationChanged()

La ricreazione di Activity è disabilitata per le modifiche alla configurazione basata sulle dimensioni quando hai android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" nel file manifest.

Consenti la ricreazione dell'attività per le modifiche alla configurazione in base alle dimensioni

Su Android 7.0 (livello API 24) e versioni successive, Activity la ricreazione è solo per i modelli basati sulle dimensioni configurazione cambia se la variazione delle dimensioni è significativa. Quando il sistema non ricrea un elemento Activity a causa di dimensioni insufficienti, il sistema potrebbe chiamare Activity.onConfigurationChanged() e View.onConfigurationChanged().

È necessario osservare alcune avvertenze in merito a Activity e View quando Activity non viene ricreato:

  • Da Android 11 (livello API 30) ad Android 13 (livello API 33), Activity.onConfigurationChanged() non viene chiamato.
  • Si è verificato un problema noto per cui View.onConfigurationChanged() potrebbe non essere chiamato in alcuni casi su Android 12L (livello API 32) e sulle prime versioni di Android 13 (livello API 33). Per ulteriori informazioni, consulta questo problema pubblico. Questo problema è stato risolto nelle versioni successive di Android 13 e Android 14.

Per codice che dipende dall'ascolto della configurazione basata sulle dimensioni modifiche, ti consigliamo di utilizzare un'utilità View con un View.onConfigurationChanged() invece di affidarsi a Activity ricreazione Activity.onConfigurationChanged().