Quando un utente naviga nell'app, esce e torna, le istanze Activity nell'app passano attraverso diversi stati nel loro ciclo di vita.
La classe Activity fornisce una serie di callback che consentono all'attività di sapere quando cambia uno stato o quando il sistema sta creando, interrompendo o riprendendo un'attività o distruggendo il processo in cui si trova l'attività.
All'interno dei metodi di callback del ciclo di vita, puoi dichiarare il comportamento della tua attività quando l'utente esce e rientra nell'attività. Ad esempio, se stai creando un video player in streaming, potresti mettere in pausa il video e terminare la connessione di rete quando l'utente passa a un'altra app. Quando l'utente torna, puoi riconnetterti alla rete e consentirgli di riprendere il video dallo stesso punto.
Ogni callback ti consente di eseguire un lavoro specifico appropriato a un determinato cambio di stato. Eseguire il lavoro giusto al momento giusto e gestire le transizioni in modo corretto rende la tua app più solida e performante. Ad esempio, una buona implementazione dei callback del ciclo di vita può aiutare la tua app a evitare quanto segue:
- Arresto anomalo se l'utente riceve una telefonata o passa a un'altra app mentre utilizza la tua app.
- Consumare risorse di sistema preziose quando l'utente non la utilizza attivamente.
- Perdita dei progressi dell'utente se esce dall'app e vi torna in un secondo momento.
- Arresto anomalo o perdita dei progressi dell'utente quando lo schermo ruota tra l'orientamento orizzontale e quello verticale.
Questo documento spiega in dettaglio il ciclo di vita dell'attività. Il documento inizia con la descrizione del paradigma del ciclo di vita. Successivamente, vengono spiegati i singoli callback: cosa succede internamente durante la loro esecuzione e cosa devi implementare durante l'esecuzione.
Poi, introduce brevemente la relazione tra lo stato dell'attività e la vulnerabilità di un processo alla terminazione da parte del sistema. Infine, vengono discussi diversi argomenti relativi alle transizioni tra gli stati delle attività.
Per informazioni sulla gestione dei cicli di vita, incluse indicazioni sulle best practice, consulta Ciclo di vita in Jetpack Compose e Salva gli stati della UI. Per scoprire come progettare un'app solida e di qualità per la produzione utilizzando le attività in combinazione con i componenti dell'architettura, consulta la Guida all'architettura delle app.
Concetti relativi al ciclo di vita dell'attività
Per gestire le transizioni tra le fasi del ciclo di vita dell'attività, la classe Activity fornisce un insieme di base di sei callback: onCreate, onStart, onResume, onPause, onStop e onDestroy. Il sistema richiama ciascuno di questi callback quando l'attività entra in un nuovo stato.
La Figura 1 presenta una rappresentazione visiva di questo paradigma.
Quando l'utente inizia a uscire dall'attività, il sistema chiama i metodi per smantellare l'attività. In alcuni casi, l'attività viene smantellata solo parzialmente e rimane ancora in memoria, ad esempio quando l'utente passa a un'altra app. In questi casi, l'attività può comunque tornare in primo piano.
Se l'utente torna all'attività, questa riprende da dove l'utente l'aveva interrotta. Con alcune eccezioni, alle app è vietato avviare attività quando sono in esecuzione in background.
La probabilità che il sistema interrompa un determinato processo, insieme alle attività al suo interno, dipende dallo stato dell'attività in quel momento. Per saperne di più sulla relazione tra lo stato e la vulnerabilità all'espulsione, consulta la sezione relativa allo stato dell'attività e all'espulsione dalla memoria.
A seconda della complessità della tua attività, probabilmente non è necessario implementare tutti i metodi del ciclo di vita. Tuttavia, è importante che tu li comprenda tutti e implementi quelli che fanno sì che la tua app si comporti come previsto dagli utenti.
Compose e il ciclo di vita
In Compose, evita di inserire la logica di business o la configurazione manuale dell'observer direttamente
all'interno dei callback delle attività come onStart o onResume. Utilizza invece effetti sensibili al ciclo di vita e osservatori sensibili allo stato che si allineano automaticamente alla presenza della UI sullo schermo.
- Raccolta sensibile al ciclo di vita: utilizza
collectAsStateWithLifecycleper utilizzare i flussi dal tuoViewModel. Questa API avvia automaticamente la raccolta quando la UI entra nello stato Started e la interrompe quando passa in background, evitando un consumo inutile di risorse. Dopo aver raccolto il flusso come stato, puoi utilizzareLifecycleEffectsper eseguire il codice quando si verifica un evento del ciclo di vita. - Flusso della logica: utilizzando queste API, l'UI reagisce allo stato del ciclo di vita in modo naturale tramite l'albero di composizione, garantendo che la logica di business venga eseguita solo quando l'utente interagisce attivamente con il componente.
Per scoprire di più su Compose e sul ciclo di vita, consulta Ciclo di vita in Jetpack Compose.
Callback del ciclo di vita
Questa sezione fornisce informazioni concettuali e di implementazione sui metodi di callback utilizzati durante il ciclo di vita dell'attività.
Alcune azioni appartengono ai metodi del ciclo di vita dell'attività. Tuttavia, inserisci il codice che implementa le azioni di un componente dipendente nel componente, anziché nel metodo del ciclo di vita dell'attività. Per farlo, devi rendere il componente dipendente sensibile al ciclo di vita. Per scoprire come rendere i componenti dipendenti sensibili al ciclo di vita, consulta Ciclo di vita in Jetpack Compose.
onCreate
Devi implementare questo callback, che viene attivato quando il sistema crea l'attività per la prima volta. Al momento della creazione, l'attività entra nello stato Creata. Nel metodo onCreate, esegui la logica di avvio di base dell'applicazione che si verifica una sola volta per l'intera durata dell'attività.
Ad esempio, l'implementazione di onCreate potrebbe associare i dati agli elenchi,
associare l'attività a un ViewModel e creare un'istanza di alcune
variabili con ambito di classe. Questo metodo riceve il parametro savedInstanceState,
che è un oggetto Bundle contenente lo stato dell'attività salvato
in precedenza. Se l'attività non è mai esistita prima, il valore dell'oggetto Bundle è null.
Se hai un componente sensibile al ciclo di vita collegato al ciclo di vita della tua attività, riceve l'evento ON_CREATE. Il metodo annotato con @OnLifecycleEvent viene chiamato in modo che il componente sensibile al ciclo di vita possa eseguire qualsiasi codice di configurazione necessario per lo stato creato.
L'esempio seguente mostra come integrare un composable Text in un'attività di base:
class ExampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // In here, we can call composables! MaterialTheme { Greeting(name = "compose") } } } } @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
La tua attività non rimane nello stato Creata. Al termine dell'esecuzione del metodo onCreate, l'attività entra nello stato Avviata e il sistema chiama i metodi onStart e onResume in rapida successione.
onStart
Quando l'attività entra nello stato Avviata, il sistema richiama onStart.
Questa chiamata rende l'attività visibile all'utente mentre l'app si prepara a portarla in primo piano e renderla interattiva. Ad esempio, questo metodo è il punto in cui viene inizializzato il codice che gestisce la UI.
Quando l'attività passa allo stato Avviata, qualsiasi componente sensibile al ciclo di vita collegato al ciclo di vita dell'attività riceve l'evento ON_START.
Il metodo onStart viene completato rapidamente e, come per lo stato Created, l'attività non rimane nello stato Started. Una volta completato questo callback, l'attività entra nello stato Ripresa e il sistema richiama il metodo onResume.
onResume
Quando l'attività entra nello stato Ripresa, viene visualizzata in primo piano e il sistema richiama il callback onResume. Questo è lo stato in cui l'app interagisce con l'utente. L'app rimane in questo stato finché non si verifica un evento che distoglie l'attenzione dall'app, ad esempio il dispositivo riceve una telefonata, l'utente passa a un'altra attività o lo schermo del dispositivo si spegne.
Quando l'attività passa allo stato Resumed, qualsiasi componente sensibile al ciclo di vita associato al ciclo di vita dell'attività riceve l'evento ON_RESUME. In questo caso, i componenti del ciclo di vita possono attivare qualsiasi funzionalità che deve essere eseguita mentre il componente è visibile e in primo piano, ad esempio l'avvio di un'anteprima della fotocamera.
Quando si verifica un evento di interruzione, l'attività entra nello stato In pausa e il sistema richiama il callback onPause.
Se l'attività torna allo stato Ripresa dallo stato In pausa, il sistema chiama nuovamente il metodo onResume. Per questo motivo, implementa onResume per inizializzare i componenti che rilasci durante onPause e per eseguire qualsiasi altra inizializzazione che deve avvenire ogni volta che l'attività entra nello stato Ripresa.
Ecco un esempio di componente sensibile al ciclo di vita che accede alla fotocamera quando
riceve l'evento ON_RESUME:
class CameraComponent : LifecycleObserver {
...
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun initializeCamera() {
if (camera == null) {
getCamera()
}
}
...
}
Il codice precedente inizializza la fotocamera una volta che LifecycleObserver
riceve l'evento ON_RESUME. In modalità multi-finestra, tuttavia, l'attività potrebbe essere completamente visibile anche quando è in stato di pausa. Ad esempio, quando l'app è in modalità multi-finestra e l'utente tocca la finestra che non contiene la tua attività, quest'ultima passa allo stato In pausa.
Se vuoi che la fotocamera sia attiva solo quando l'app viene ripresa (visibile e attiva
in primo piano), inizializza la fotocamera dopo l'evento ON_RESUME
mostrato in precedenza. Se vuoi mantenere attiva la fotocamera mentre l'attività è in pausa, ma visibile, ad esempio in modalità multi-finestra, inizializza la fotocamera dopo l'evento ON_START.
Tuttavia, se la fotocamera è attiva mentre l'attività è in pausa, l'accesso alla fotocamera potrebbe essere negato a un'altra app ripresa in modalità multi-finestra. A volte è necessario mantenere attiva la fotocamera mentre l'attività è in pausa, ma ciò potrebbe peggiorare l'esperienza utente complessiva.
Per questo motivo, valuta attentamente in quale fase del ciclo di vita è più appropriato assumere il controllo delle risorse di sistema condivise nel contesto della modalità multi-finestra. Per scoprire di più sul supporto della modalità multi-finestra, consulta Supporto della modalità multi-finestra.
Indipendentemente dall'evento di creazione che scegli per eseguire un'operazione di inizializzazione, assicurati di utilizzare l'evento del ciclo di vita corrispondente per rilasciare la risorsa. Se inizializzi un elemento dopo l'evento ON_START, rilascialo o terminalo dopo l'evento ON_STOP. Se l'inizializzazione avviene dopo l'evento ON_RESUME, il rilascio avviene dopo l'evento ON_PAUSE.
Lo snippet di codice precedente inserisce il codice di inizializzazione della fotocamera in un componente sensibile al ciclo di vita. In alternativa, puoi inserire questo codice direttamente nei callback del ciclo di vita dell'attività, come onStart e onStop, ma non lo consigliamo. L'aggiunta di questa logica a un componente indipendente e sensibile al ciclo di vita ti consente di riutilizzare il componente in più attività senza dover duplicare il codice. Per scoprire come creare un componente sensibile al ciclo di vita, consulta
Ciclo di vita in Jetpack Compose.
onPause
Il sistema chiama questo metodo come prima indicazione che l'utente sta uscendo dalla tua attività, anche se non sempre significa che l'attività viene eliminata. Indica che l'attività non è più in primo piano, ma è ancora visibile se l'utente è in modalità multi-finestra. Un'attività può entrare in questo stato per diversi motivi:
- Un evento che interrompe l'esecuzione dell'app, come descritto nella sezione relativa al callback
onResume, mette in pausa l'attività corrente. Questo è il caso più comune. - In modalità multi-finestra, solo un'app è attiva alla volta e il sistema mette in pausa tutte le altre.
- L'apertura di una nuova attività semitrasparente, ad esempio una finestra di dialogo, mette in pausa l'attività che copre. Finché l'attività è parzialmente visibile, ma non è selezionata, rimane in pausa.
Quando un'attività passa allo stato Pausa, qualsiasi componente sensibile al ciclo di vita collegato al ciclo di vita dell'attività riceve l'evento ON_PAUSE. In questa fase, i componenti del ciclo di vita possono interrompere qualsiasi funzionalità che non deve essere eseguita mentre il componente non è in primo piano, ad esempio l'anteprima della fotocamera.
Utilizza il metodo onPause per mettere in pausa o modificare le operazioni che non possono continuare o che potrebbero continuare con moderazione, mentre Activity è in stato di pausa e che prevedi di riprendere a breve.
Puoi anche utilizzare il metodo onPause per rilasciare risorse di sistema, handle per i sensori (come il GPS) o qualsiasi risorsa che influisca sulla durata della batteria mentre l'attività è in pausa e l'utente non ne ha bisogno.
Tuttavia, come indicato nella sezione relativa a onResume, un'attività in pausa potrebbe
essere ancora completamente visibile se l'app è in modalità multi-finestra. Valuta la possibilità di utilizzare onStop anziché onPause per rilasciare o regolare completamente le risorse e le operazioni relative alla UI per supportare meglio la modalità multi-finestra.
Il seguente esempio di LifecycleObserver che reagisce all'evento ON_PAUSE è la controparte dell'esempio di evento ON_RESUME precedente, che rilascia la fotocamera che si inizializza dopo la ricezione dell'evento ON_RESUME:
class CameraComponent : LifecycleObserver {
...
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun releaseCamera() {
camera?.release()
camera = null
}
...
}
Questo esempio inserisce il codice di rilascio della videocamera dopo che l'evento ON_PAUSE viene ricevuto da LifecycleObserver.
L'esecuzione di onPause è molto breve e non offre necessariamente il tempo sufficiente per eseguire le operazioni di salvataggio. Per questo motivo, non utilizzare onPause per salvare i dati dell'applicazione o dell'utente, effettuare chiamate di rete o eseguire transazioni di database.
Questo lavoro potrebbe non essere completato prima del completamento del metodo.
Esegui invece le operazioni di arresto con carico elevato durante onStop. Per saperne di più sulle operazioni adatte da eseguire durante onStop, consulta la sezione successiva. Per saperne di più sul salvataggio dei dati, consulta la sezione relativa al salvataggio e al ripristino dello stato.
Il completamento del metodo onPause non significa che l'attività esce dallo stato In pausa. L'attività rimane in questo stato finché non riprende o non diventa completamente invisibile all'utente. Se l'attività riprende, il sistema richiama di nuovo il callback onResume.
Se l'attività torna dallo stato In pausa allo stato Ripresa, il sistema mantiene l'istanza Activity residente in memoria, richiamandola quando il sistema richiama onResume. In questo scenario, non è necessario reinizializzare i componenti creati durante uno dei metodi di callback che precedono lo stato Ripreso. Se l'attività diventa completamente invisibile, il sistema chiama onStop.
onStop
Quando l'attività non è più visibile all'utente, entra nello stato Interrotta e il sistema richiama il callback onStop. Questo può accadere quando un'attività appena avviata copre l'intero schermo. Il sistema chiama anche onStop
quando l'attività termina l'esecuzione e sta per essere terminata.
Quando l'attività passa allo stato Interrotta, qualsiasi componente sensibile al ciclo di vita associato al ciclo di vita dell'attività riceve l'evento ON_STOP. In questa fase, i componenti del ciclo di vita possono interrompere qualsiasi funzionalità che non deve essere eseguita mentre il componente non è visibile sullo schermo.
Nel metodo onStop, rilascia o regola le risorse non necessarie mentre l'app non è visibile all'utente. Ad esempio, l'app potrebbe mettere in pausa le animazioni o passare da aggiornamenti della posizione dettagliati ad aggiornamenti approssimativi. L'utilizzo di onStop
anziché di onPause consente di continuare il lavoro relativo alla UI, anche quando l'utente
visualizza la tua attività in modalità multi-finestra.
Inoltre, utilizza onStop per eseguire operazioni di arresto che richiedono un utilizzo relativamente elevato della CPU. Ad esempio, se non riesci a trovare un momento migliore per salvare le informazioni in un database, puoi farlo durante onStop. L'esempio seguente mostra un'implementazione di onStop che salva i contenuti di una bozza di nota nell'archiviazione permanente:
override fun onStop() {
super.onStop()
// Delegate the save operation to the ViewModel, which handles the
// background thread operations (e.g., using Kotlin Coroutines and Room).
noteViewModel.saveDraft()
}
Quando l'attività entra nello stato Interrotta, l'oggetto Activity viene mantenuto
residente in memoria: mantiene tutte le informazioni sullo stato e sui membri, ma non è
collegato al gestore delle finestre. Quando l'attività riprende, richiama queste informazioni.
Dallo stato Interrotta, l'attività torna a interagire con l'utente o termina l'esecuzione e scompare. Se l'attività torna in primo piano, il sistema richiama onRestart. Se l'esecuzione di Activity è terminata, il sistema chiama onDestroy.
onDestroy
onDestroy viene chiamato prima che l'attività venga eliminata. Il sistema richiama questo callback per uno dei seguenti motivi:
- L'attività sta per terminare perché l'utente l'ha ignorata completamente o perché è stato chiamato
finishnell'attività. - Il sistema sta distruggendo temporaneamente l'attività a causa di una modifica della configurazione, ad esempio la rotazione del dispositivo o l'attivazione della modalità multi-finestra.
Quando l'attività passa allo stato distrutto, qualsiasi componente sensibile al ciclo di vita
associato al ciclo di vita dell'attività riceve l'evento ON_DESTROY. In questa fase, i componenti del ciclo di vita possono eseguire le operazioni di pulizia necessarie prima che l'oggetto Activity venga eliminato.
Anziché inserire la logica in Activity per determinare il motivo per cui viene eliminata, utilizza un oggetto ViewModel per contenere i dati di visualizzazione pertinenti per Activity. Se Activity viene ricreato a causa di una modifica della configurazione,
ViewModel non deve fare nulla, poiché viene conservato e assegnato alla
successiva istanza Activity.
Se Activity non viene ricreato, viene chiamata la chiamata al metodo onCleared di ViewModel, dove può ripulire tutti i dati necessari prima di essere eliminato. Puoi distinguere tra questi due scenari con il metodo isFinishing.
Se l'attività sta per terminare, onDestroy è l'ultimo callback del ciclo di vita che riceve. Se onDestroy viene chiamato in seguito a una modifica della configurazione, il sistema crea immediatamente una nuova istanza dell'attività e chiama onCreate sulla nuova istanza nella nuova configurazione.
Il callback onDestroy rilascia tutte le risorse non rilasciate dai callback precedenti, come onStop.
Stato dell'attività ed espulsione dalla memoria
Il sistema termina i processi quando deve liberare RAM. La probabilità che il sistema termini un determinato processo dipende dallo stato del processo in quel momento. Lo stato del processo, a sua volta, dipende dallo stato dell'attività in esecuzione nel processo. La tabella 1 mostra le correlazioni tra lo stato del processo, lo stato dell'attività e la probabilità che il sistema termini il processo. Questa tabella si applica solo se un processo non esegue altri tipi di componenti dell'applicazione.
Probabilità di essere uccisi |
Stato elaborazione |
Stato finale dell'attività |
Minima |
In primo piano (con o in procinto di ottenere lo stato attivo) |
Ripristinato |
Bassa |
Visibile (senza stato attivo) |
Avviata/In pausa |
Superiore |
Background (invisible) |
Arrestato |
Massima |
Vuoto |
Eliminata |
Tabella 1. Relazione tra il ciclo di vita del processo e lo stato dell'attività.
Il sistema non termina mai un'attività direttamente per liberare memoria. Al contrario, termina il processo in cui viene eseguita l'attività, distruggendo non solo l'attività, ma anche tutto ciò che viene eseguito nel processo. Per scoprire come conservare e ripristinare lo stato della UI della tua attività quando si verifica l'interruzione del processo avviata dal sistema, consulta la sezione relativa al salvataggio e al ripristino dello stato.
L'utente può anche terminare un processo utilizzando Gestione applicazioni, in Impostazioni, per terminare l'app corrispondente.
Per saperne di più sui processi, consulta la panoramica di processi e thread.
Salvataggio e ripristino dello stato temporaneo della UI
Un utente si aspetta che lo stato della UI di un'attività rimanga invariato durante una modifica della configurazione, ad esempio la rotazione o il passaggio alla modalità multi-finestra. Tuttavia, per impostazione predefinita, il sistema elimina l'attività quando si verifica una modifica della configurazione, cancellando qualsiasi stato della UI memorizzato nell'istanza dell'attività.
Analogamente, un utente si aspetta che lo stato della UI rimanga invariato se passa temporaneamente dalla tua app a un'altra e poi torna alla tua app in un secondo momento. Tuttavia, il sistema può eliminare il processo della tua applicazione mentre l'utente non la utilizza e la tua attività è interrotta.
Quando i vincoli di sistema distruggono l'attività, conserva lo stato dell'interfaccia utente temporaneo dell'utente utilizzando una combinazione di ViewModel (per la logica di business complessa e lo stato della schermata), l'API Jetpack Compose rememberSaveable (per lo stato dell'interfaccia utente leggero) e/o lo spazio di archiviazione locale. Per scoprire di più sulle aspettative degli utenti rispetto al comportamento del sistema e su come preservare al meglio i dati complessi dello stato della UI durante l'attività avviata dal sistema e l'interruzione del processo, consulta Salva gli stati della UI.
rememberSaveable sopravvive automaticamente sia alle modifiche alla configurazione sia
all'interruzione del processo avviata dal sistema raggruppando lo stato in background, offrendo
un'esperienza fluida senza la necessità di codice boilerplate a livello di attività.
Stato istanza
Esistono alcuni scenari in cui l'attività viene eliminata a causa del normale comportamento dell'app, ad esempio quando l'utente preme il pulsante Indietro o l'attività segnala la propria eliminazione chiamando il metodo finish.
Quando l'attività viene eliminata perché l'utente preme Indietro o l'attività termina, il concetto di questa istanza Activity sia per il sistema sia per l'utente scompare definitivamente. In questi scenari, l'aspettativa dell'utente corrisponde al comportamento del sistema e non devi eseguire ulteriori operazioni.
Tuttavia, se il sistema elimina l'attività a causa di vincoli di sistema (ad esempio una modifica alla configurazione o una pressione della memoria), anche se l'istanza Activity effettiva non esiste più, il sistema ricorda che esisteva. Se l'utente tenta di tornare all'attività, il sistema crea una nuova istanza di quell'attività utilizzando un insieme di dati salvati che descrivono lo stato dell'attività al momento della sua distruzione.
I dati salvati che il sistema utilizza per ripristinare lo stato precedente sono chiamati stato dell'istanza. In pratica, si tratta di una raccolta di coppie chiave-valore. Per impostazione predefinita, il sistema utilizza lo stato dell'istanza per salvare le informazioni di base sul layout dell'interfaccia utente, ad esempio l'input di testo dell'utente o le posizioni di scorrimento.
Puoi collegarti a questo comportamento del sistema utilizzando rememberSaveable. Se l'istanza dell'attività viene eliminata e ricreata, qualsiasi stato della UI inserito in rememberSaveable viene ripristinato automaticamente, senza che sia necessario alcun codice aggiuntivo a livello di attività.
Tuttavia, è probabile che la tua attività contenga informazioni sullo stato più complesse che
vorresti ripristinare, come dati utente, risposte di rete o variabili membro
che monitorano i progressi dell'utente. Il meccanismo dello stato dell'istanza (e, per estensione,
rememberSaveable) non è appropriato per conservare più di una quantità minima
di dati, perché richiede la serializzazione sul thread principale e consuma
memoria del processo di sistema.
Per conservare più di una quantità molto ridotta di dati, adotta un approccio combinato utilizzando lo spazio di archiviazione locale persistente, la classe ViewModel e l'innalzamento dello stato di Compose, come descritto in Salva gli stati della UI.
Salva lo stato della UI semplice e leggero utilizzando rememberSaveable
Quando l'attività inizia a interrompersi, il sistema si prepara a salvare le informazioni sullo stato in un bundle di stato dell'istanza. Per agganciarti a questo comportamento del sistema, utilizza
rememberSaveable direttamente all'interno delle tue funzioni componibili.
rememberSaveable salva e ripristina automaticamente lo stato temporaneo della UI, ad esempio l'input di testo dell'utente o le posizioni di scorrimento, durante la ricreazione dell'attività.
Per salvare informazioni sullo stato personalizzate e leggere (come i progressi di un utente in un gioco), dichiara lo stato utilizzando rememberSaveable. Il framework Compose gestisce la serializzazione nel bundle dello stato dell'istanza in background:
var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) { mutableStateOf( TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length)) ) }
Per salvare dati persistenti, come le preferenze dell'utente o i dati di un database, sfrutta
le opportunità appropriate quando la tua attività è in primo piano. Se non si presenta questa opportunità, salva i dati persistenti durante il metodo onStop.
Ripristina lo stato della UI dell'attività utilizzando lo stato dell'istanza salvata
Quando l'attività viene ricreata dopo essere stata eliminata, il ripristino dello stato è automatico. Quando utilizzi rememberSaveable, non devi scrivere alcuna logica di ripristino esplicita, controllare la presenza di bundle null o eseguire l'override dei callback delle attività. Il codice che inizializza e salva lo stato lo ripristina anche senza problemi quando l'attività viene ripresa:
var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) { mutableStateOf( TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length)) ) }
Attività e navigazione
È probabile che un'app passi da una schermata all'altra molte volte durante il suo ciclo di vita, ad esempio quando l'utente tocca il pulsante Indietro del dispositivo o seleziona una nuova destinazione. Le app per Android moderne in genere utilizzano un'architettura con una singola attività.
Anziché avviare una nuova Activity per ogni schermata, la tua app ospita una singola Activity e utilizza il componente Navigation per scambiare le schermate componibili all'interno di quell'attività.
Per scoprire come implementare una navigazione moderna incentrata su Compose, consulta la guida alla libreria Navigation 3 di Jetpack Compose.
Avvio di un'attività da un'altra
A un certo punto, un'attività potrebbe dover avviare un'altra attività. Questa esigenza si presenta, ad esempio, quando un'app deve passare dalla schermata corrente a una nuova.
A seconda che l'attività voglia o meno un risultato dall'attività che sta per iniziare, puoi avviare la nuova attività utilizzando il metodo startActivity o il metodo startActivityForResult. In entrambi i casi, passi un oggetto Intent.
L'oggetto Intent specifica l'attività esatta che vuoi avviare o descrive il tipo di azione che vuoi eseguire. Il sistema seleziona l'attività appropriata per te, che può anche provenire da un'applicazione diversa. Un oggetto Intent può anche contenere piccole quantità di dati che verranno utilizzati dall'attività avviata. Per saperne di più sulla classe Intent, consulta Intent e filtri per intent.
startActivity
Se l'attività appena avviata non deve restituire un risultato, l'attività corrente può avviarla chiamando il metodo startActivity.
Quando lavori all'interno della tua applicazione, spesso devi semplicemente avviare un'attività nota. Ad esempio, il seguente snippet di codice mostra come avviare un'attività chiamata SignInActivity.
val context = LocalContext.current
Button(onClick = {
val intent = Intent(context, SignInActivity::class.java)
context.startActivity(intent)
}) {
Text("Sign In")
}
Avvio di attività esterne
Mentre la navigazione interna dell'app è gestita da Navigation, la tua Activity dovrà occasionalmente avviare altre attività. In genere, questo accade quando vuoi utilizzare un'app esterna per eseguire un'azione specifica, ad esempio aprire un browser web, inviare un'email o scattare una foto.
Per farlo, utilizza un oggetto Intent per descrivere il tipo di azione che vuoi eseguire e il sistema avvia l'attività appropriata da un'altra applicazione.
Ad esempio, se vuoi consentire all'utente di inviare un'email, puoi creare il seguente intent:
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)
Se devi avviare un'attività esterna e ottenere un risultato (ad esempio chiedere all'app della fotocamera di scattare una foto e restituire l'immagine), utilizza le moderne Activity API dei risultati anziché il callback startActivityForResult deprecato.
Attività di coordinamento
Quando un'attività ne avvia un'altra, entrambe subiscono transizioni del ciclo di vita. La prima attività smette di funzionare ed entra nello stato In pausa o Interrotta, mentre viene creata l'altra attività. Se queste attività condividono dati salvati su disco o altrove, è importante capire che la prima attività non viene interrotta completamente prima della creazione della seconda. Invece, il processo di avvio della seconda istanza si sovrappone al processo di arresto della prima.
L'ordine dei callback del ciclo di vita è ben definito, in particolare quando le due attività si trovano nello stesso processo, ovvero nella stessa app, e una avvia l'altra. Ecco l'ordine delle operazioni che si verificano quando l'Attività A avvia l'Attività B:
- Viene eseguito il metodo
onPausedell'attività A. - I metodi
onCreate,onStarteonResumedell'Attività B vengono eseguiti in sequenza. L'attività B ora ha lo stato attivo dell'utente. - Se l'Attività A non è più visibile sullo schermo, viene eseguito il relativo metodo
onStop.
Questa sequenza di callback del ciclo di vita ti consente di gestire la transizione delle informazioni da un'attività all'altra.
Risorse aggiuntive
Per scoprire di più sul ciclo di vita dell'attività, consulta le seguenti risorse aggiuntive: