Sous Android 9 (et versions antérieures), les applications passaient à l'état PAUSED
dans les cas suivants:
- Une nouvelle activité translucide a été lancée au-dessus de l'application, alors que celle-ci était toujours visible (et n'a donc pas été arrêtée).
- L'activité n'est plus au centre de l'attention, mais n'est pas masquée et l'utilisateur peut interagir avec elle. Par exemple, en mode multifenêtre, un certain nombre d'activités peuvent être visibles et recevoir des entrées tactiles simultanément.
Ces situations diffèrent par le nombre de mises en veille d'une application, mais ne peuvent pas être distinguées au niveau de l'application.
Dans Android 10, toutes les activités les plus élevées pouvant être mises au point dans les piles visibles se trouvent dans l'état RESUMED
. Cela améliore la compatibilité avec les modes Multifenêtre et MD pour les applications qui utilisent onPause()
au lieu de onStop()
pour arrêter l'actualisation de l'UI et l'interaction avec l'utilisateur. Autrement dit :
- Les deux activités en mode Écran partagé sont réactivées.
- Toutes les activités visibles en haut de l'écran en mode fenêtrage de format libre sont reprises.
- Les activités sur plusieurs écrans peuvent être reprises en même temps.
Figure 1 : Multireprise sur un appareil pliable
Figure 2. Multireprise en mode bureau
Les activités peuvent résider à l'état PAUSED
lorsqu'elles ne peuvent pas être sélectionnées ou qu'elles sont partiellement masquées, par exemple:
- Dans un écran partagé réduit (avec le lanceur d'applications sur le côté), l'activité supérieure n'est pas réactivée, car elle n'est pas sélectionnable.
- En mode Picture-in-picture, l'activité n'est pas réactivée, car elle n'est pas sélectionnable.
- Lorsque les activités sont recouvertes par d'autres activités transparentes de la même pile.
Cette approche indique aux applications qu'une activité ne peut recevoir des entrées d'un utilisateur qu'à l'état RESUMED
. Avant Android 10, les activités pouvaient également recevoir des entrées dans l'état PAUSED
(par exemple, essayez de toucher simultanément les deux activités en mode Écran partagé sur un appareil exécutant Android 9).
Pour conserver le signal resumed des versions Android précédentes (et pour communiquer quand les applications doivent obtenir l'accès à des ressources en accès exclusif ou singleton), Android 10 inclut un nouveau rappel:
Activity#onTopResumedActivityChanged(boolean onTop)
Lorsqu'il est appelé, ce rappel est appelé entre Activity#onResume()
et Activity#onPause()
. Ce rappel est facultatif et peut être ignoré. Ainsi, une activité peut passer d'un état RESUMED
à un état PAUSED
sans devenir la plus élevée du système. Par exemple, en mode multifenêtre.
Étant donné que ce rappel est facultatif, il ne fait pas partie du cycle de vie de l'activité et doit être utilisé rarement.
L'activité précédente de premier plan reprend et termine l'exécution de onTopResumedActivity(false)
avant que l'activité suivante de premier plan ne reçoive onTopResumedActivity(true)
, sauf si l'activité précédente prend trop de temps à gérer l'appel de méthode et atteint le délai avant expiration de 500 ms.
Compatibilité
Pour assurer la compatibilité lors de la mise en œuvre de la reprise multiple, envisagez ces solutions.
Plusieurs activités réactivées dans un même processus d'application
- Problème. Sous Android 9 et versions antérieures, une seule activité du système est réactivée à la fois. Toutes les transitions entre les activités impliquent de suspendre une activité avant d'en reprendre une autre. Certaines applications et frameworks (comme Flutter ou LocalActivityManager d'Android) utilisent ce fait et stockent l'état de l'activité reprise dans des singletons.
- Solution. Sous Android 9 et versions antérieures, si deux activités du même processus sont toutes deux reprises, le système ne reprend que l'activité dont l'ordre de priorité est le plus élevé. Les applications ciblant Android 10 peuvent prendre en charge la reprise simultanée de plusieurs activités.
Accès simultané à la caméra
- Problèmes Ces problèmes sont également présents dans Android 9 et versions antérieures. Par exemple, une activité en plein écran et réactivée peut perdre le focus de la caméra au profit d'une activité mise en pause en haut de l'écran en mode Picture-in-picture, mais être plus exposée avec l'adoption plus large des modes multifenêtre et multi-écran.
- En raison des modifications apportées à l'état
RESUME
, les applications peuvent être déconnectées de la caméra même en cas de reprise. Pour y remédier, les applications doivent gérer la déconnexion de la caméra sans planter. Lorsqu'elles sont déconnectées, les applications reçoivent un rappel de déconnexion et tous les appels à l'API commencent à générer une exceptionCameraAccessException
. resizeableActivity=false
ne garantit pas un accès exclusif à l'appareil photo, car d'autres applications utilisant l'appareil photo peuvent être ouvertes sur d'autres écrans.
- En raison des modifications apportées à l'état
- Solutions. Les développeurs doivent inclure une logique pour les cas où une application est déconnectée de la caméra. Si une application est déconnectée de la caméra, elle doit surveiller les rappels de disponibilité de la caméra pour essayer de se reconnecter et de continuer à utiliser la caméra. En plus du rappel
CameraManager#AvailabilityCallback#onCameraAvailable()
existant, Android 10 a ajoutéCameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged()
, qui couvre le cas où le ciblage (et la priorité de l'appareil photo) bascule entre plusieurs activités reprises. Les développeurs d'applications doivent utiliser ces deux rappels pour déterminer le bon moment pour essayer d'accéder à la caméra.
Multireprise
Sous Android 10, l'état du cycle de vie de l'activité est déterminé par la visibilité et l'ordre de plan. Pour vous assurer que l'état correct est appliqué après la mise à jour de la visibilité d'une activité et évaluer l'état de cycle de vie applicable, appelez la méthode ActivityRecord#makeActiveIfNeeded()
à partir de différents emplacements. Dans Android 10, "actif" signifie RESUMED
ou PAUSED
et ne fonctionne que dans ces deux cas.
Dans Android 10, la reprise d'une activité est suivie séparément dans chaque pile au lieu d'un seul emplacement dans le système. En effet, plusieurs transitions d'activité peuvent être effectuées simultanément en mode multifenêtre. Pour en savoir plus, consultez ActivityStack#mInResumeTopActivity
.
Rappel d'activité de reprise
Après les actions pouvant entraîner une modification de l'activité principale (telles que le lancement, la reprise ou la modification de l'ordre z), ActivityStackSupervisor#updateTopResumedActivityIfNeeded()
est appelé. Cette méthode vérifie si l'activité la plus réactivée a changé et effectue la mise à jour si nécessaire. Si l'activité précédente ayant été réactivée en premier n'a pas libéré l'état de réactivation en premier, un message de perte de l'état de réactivation en premier lui est envoyé et un délai avant expiration est planifié côté serveur (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()
). Un rapport sur l'état de réactivation en premier est envoyé à l'activité suivante après que l'activité précédente a libéré l'état ou lorsqu'un délai avant expiration a été atteint (voir les utilisations de:
ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()
Un nouvel élément de transaction TopResumedActivityChangeItem
a été ajouté pour signaler aux clients les changements d'état les plus repris et exploite l'architecture ActivityLifecycler
d'Android 9.
L'état de reprise de l'activité principale est stocké côté client. Chaque fois que l'activité passe à RESUMED
ou PAUSED
, elle vérifie également si le rappel onTopResumedActivityChanged()
doit être appelé. Cela permet un certain découplage dans la communication des états de cycle de vie et de l'état de reprise de premier plan entre les côtés serveur et client.