In Android 9 (e versioni precedenti), le app venivano inserite nello stato PAUSED
quando:
- Una nuova attività traslucida è stata avviata sopra l'app, mentre l'app era ancora visibile (e quindi non è stata interrotta).
- L'attività ha perso lo stato attivo, ma non era nascosta e l'utente poteva interagire con essa. Ad esempio, in modalità multi-finestra, è possibile visualizzare più attività e ricevere input tocco contemporaneamente.
Queste situazioni differiscono per la quantità di messa in pausa che un'app deve eseguire, ma non possono essere distinta a livello di app.
In Android 10, tutte le attività che possono essere messe a fuoco in primo piano nelle serie visibili si trovano nello stato RESUMED
. In questo modo, viene migliorata la compatibilità con le modalità Multi-Window e MD per le app che utilizzano onPause()
anziché onStop()
per interrompere l'aggiornamento dell'interfaccia utente e l'interazione con l'utente. Ciò significa che:
- Entrambe le attività in schermo diviso vengono riprese.
- Tutte le attività più visibili in modalità di visualizzazione delle finestre in formato libero vengono riprese.
- È possibile riprendere contemporaneamente le attività su più schermate.
Figura 1. Ripristino multiplo su un dispositivo pieghevole
Figura 2. Riprendi più volte in modalità desktop
Le attività possono trovarsi nello stato PAUSED
quando non è possibile metterle a fuoco o sono parzialmente occultate, ad esempio:
- In una schermata divisa ridotta a icona (con il programma di avvio a lato), l'attività in primo piano non viene ripresa perché non è possibile impostarla come attiva.
- In modalità Picture in picture, l'attività non viene ripresa perché non è possibile attivare il relativo stato attivo.
- Quando le attività sono coperte da altre attività trasparenti nello stesso stack.
Questo approccio indica alle app che un'attività può ricevere input da un
utente solo nello stato RESUMED
. Prima di Android 10,
le attività potevano anche ricevere input nello stato PAUSED
(ad esempio, prova a toccare
contemporaneamente entrambe le attività in split screen su un dispositivo con Android 9).
Per preservare l'indicatore resumed delle release Android precedenti (e per comunicare quando le app devono ottenere l'accesso a risorse con accesso esclusivo o singleton), Android 10 include un nuovo callback:
Activity#onTopResumedActivityChanged(boolean onTop)
Quando viene richiamato, questo callback viene chiamato tra Activity#onResume()
e Activity#onPause()
. Questo callback è facoltativo e può essere ignorato,
in modo che un'attività possa passare da uno stato RESUMED
a uno stato PAUSED
senza diventare la più importante nel sistema. Ad esempio, in modalità multi-finestra.
Poiché questo callback è facoltativo, non fa parte del ciclo di vita
dell'attività e dovrebbe essere utilizzato raramente.
L'attività principale precedentemente ripresa riceve e completa l'esecuzione di
onTopResumedActivity(false)
prima che l'attività principale successiva ripresa
riceva onTopResumedActivity(true)
, a meno che l'attività precedente
non impieghi troppo tempo per gestire la chiamata al metodo e raggiunga il timeout di 500 ms.
Compatibilità
Per mantenere la compatibilità durante l'implementazione del salvataggio multiplo, valuta queste soluzioni.
Più attività riprese in un unico processo dell'app
- Problema. In Android 9 e versioni precedenti, viene ripresa solo un'attività alla volta nel sistema. Tutte le transizioni tra attività comportano la messa in pausa di un'attività prima di riprendere un'altra. Alcune app e framework (come Flutter o LocalActivityManager di Android) sfruttano questo fatto e memorizzano lo stato dell'attività ripresa in oggetti singleton.
- Soluzione. In Android 9 e versioni precedenti, se vengono entrambe riprese due attività dello stesso processo, il sistema riprende solo l'attività più alta nell'ordine Z. Le app destinate ad Android 10 possono supportare la ripresa di più attività contemporaneamente.
Accesso simultaneo alla fotocamera
- Problemi. Questi problemi sono presenti anche su Android 9 e versioni precedenti. Ad esempio, un'attività a schermo intero e ripresa può perdere l'attenzione della fotocamera a favore di un'attività in pausa in alto in modalità Picture in picture, ma diventare più visibile con l'adozione più ampia delle modalità multi-finestra e multi-display.
- A causa delle modifiche apportate allo stato
RESUME
, le app potrebbero essere disconnesse dalla videocamera anche durante la ripresa. Per risolvere il problema, le app devono gestire la disconnessione della videocamera senza arrestarsi in modo anomalo. Quando la connessione viene interrotta, le app ricevono un callback di disconnessione e tutte le chiamate all'API iniziano a generareCameraAccessException
. resizeableActivity=false
non garantisce l'accesso esclusivo alla fotocamera, perché altre app che utilizzano la fotocamera possono essere aperte su altri display.
- A causa delle modifiche apportate allo stato
- Soluzioni. Gli sviluppatori devono includere la logica per quando un'app viene scollegata dalla videocamera. Se un'app è disconnessa dalla videocamera, deve monitorare i callback di disponibilità della videocamera per provare a riconnettersi e continuare a utilizzarla. Oltre al callback
CameraManager#AvailabilityCallback#onCameraAvailable()
esistente, Android 10 ha aggiuntoCameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged()
, che copre il caso in cui lo stato attivo (e la priorità della fotocamera) passi da una a più attività riprese. Gli sviluppatori di app devono utilizzare entrambi questi callback per determinare un buon momento per provare ad accedere alla videocamera.
Riprendi da dove avevi interrotto
In Android 10, lo stato del ciclo di vita dell'attività è determinato dalla visibilità e dall'ordine Z. Per assicurarti che lo stato corretto dopo gli aggiornamenti della visibilità su un'attività sia corretto e valutare quale stato del ciclo di vita sia applicabile, invoca il metodo ActivityRecord#makeActiveIfNeeded()
da posizioni diverse. In Android 10, attivo significa RESUMED
o
PAUSED
e funziona solo in queste due istanze.
In Android 10, la ripresa di un'attività viene monitorata separatamente in ogni pila anziché nella singola posizione del sistema. Questo perché in modalità multi-finestra è possibile eseguire contemporaneamente più transizioni di attività. Per maggiori dettagli, vedi ActivityStack#mInResumeTopActivity
.
Callback dell'attività più ripresa
Dopo azioni che possono comportare una modifica dell'attività principale (ad esempio l'avvio, la ripresa o la modifica dell'ordine Z dell'attività), viene invocato ActivityStackSupervisor#updateTopResumedActivityIfNeeded()
. Questo metodo controlla se l'attività ripresa più in alto è cambiata ed esegue l'aggiornamento, se necessario. Se l'attività di primo piano precedente non ha rilasciato lo stato di primo piano, viene inviato un messaggio di perdita dello stato di primo piano e viene pianificato un timeout lato server (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()
).
Un report dello stato di primo piano viene inviato all'attività successiva dopo che quella precedente ha rilasciato lo stato o quando è stato raggiunto un timeout (vedi gli utilizzi di:
ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()
È stato aggiunto un nuovo elemento di transazione TopResumedActivityChangeItem
per segnalare ai clienti le modifiche dello stato di ripresa superiore e sfrutta l'architettura ActivityLifecycler
di Android 9.
Lo stato di ripresa superiore viene memorizzato lato client e ogni volta che l'attività passa a RESUMED
o PAUSED
viene anche controllato se deve essere invocato il callback onTopResumedActivityChanged()
. Ciò consente un certo disaccoppiamento nella comunicazione degli stati del ciclo di vita
e dello stato di ripresa più recente tra il lato server e il lato client.