Multi-CV

Sous Android 9 (et versions antérieures), les applications passaient à l'état PAUSED lorsque :

  • Une nouvelle activité translucide lancée au-dessus de l'application, alors que l'application était encore visible (et n'a donc pas été arrêtée).
  • L'activité a perdu le focus, mais n'était pas masquée et l'utilisateur pouvait interagir avec elle. Par exemple, en mode multi-fenêtres, un certain nombre d’activités peuvent être visibles et recevoir une saisie tactile simultanément.

Ces situations diffèrent par le nombre de pauses qu'une application doit effectuer, mais ne peuvent pas être distinguées au niveau de l'application.

Dans Android 10, toutes les activités les plus focalisables dans les piles visibles résident à l'état RESUMED . Cela améliore la compatibilité avec les modes Multi-Window et MD pour les applications qui utilisent onPause() au lieu de onStop() pour arrêter d'actualiser l'interface utilisateur et d'interagir avec l'utilisateur. Cela signifie:

  • Les deux activités en écran partagé reprennent.
  • Toutes les activités les plus visibles en mode fenêtrage de forme libre reprennent.
  • Les activités sur plusieurs écrans peuvent être reprises en même temps.

Figure 1. Multi-CV sur un appareil pliable

Figure 2. Multi-CV en mode bureau

Les activités peuvent résider dans l'état PAUSED lorsqu'elles ne peuvent pas être ciblées ou sont partiellement masquées, telles que :

  • Dans un écran partagé réduit (avec lanceur sur le côté), l'activité principale ne reprend pas car elle n'est pas focalisable.
  • En mode image dans l'image, l'activité ne reprend pas car la mise au point n'est pas possible.
  • Lorsque les activités sont couvertes par d’autres activités transparentes dans la même pile.

Cette approche indique aux applications qu'une activité peut recevoir des entrées d'un utilisateur uniquement dans l'état RESUMED . Avant Android 10, les activités pouvaient également recevoir des entrées à l'état PAUSED (par exemple, essayez de toucher simultanément les deux activités en écran partagé sur un appareil exécutant Android 9).

Pour conserver le signal de reprise des versions précédentes d'Android (et pour communiquer quand les applications doivent obtenir l'accès aux ressources à accès exclusif ou singleton), Android 10 inclut un nouveau rappel :

Activity#onTopResumedActivityChanged(boolean onTop)

Lorsqu'il est invoqué, ce rappel est appelé entre Activity#onResume() et Activity#onPause() . Ce rappel est facultatif et peut être ignoré, de sorte qu'une activité peut passer d'un état RESUMED à un état PAUSED sans devenir la plus haute du système. Par exemple, en mode multi-fenêtres. Ce rappel étant facultatif, il ne fait pas partie du cycle de vie de l'activité et doit être rarement utilisé.

L'activité précédente reprise en premier reçoit et termine l'exécution de onTopResumedActivity(false) avant que l'activité reprise en premier suivante reçoive onTopResumedActivity(true) , sauf si l'activité précédente prend trop de temps pour gérer l'appel de méthode et atteint le délai d'expiration de 500 ms.

Compatibilité

Pour maintenir la compatibilité lors de la mise en œuvre de plusieurs CV, envisagez ces solutions.

Plusieurs activités reprises dans un seul processus d'application

  • Problème. Sous Android 9 et versions antérieures, une seule activité du système est reprise à la fois. Toutes les transitions entre activités impliquent de mettre une activité en pause avant d’en reprendre une autre. Certaines applications et frameworks (tels que Flutter ou LocalActivityManager d'Android) utilisent ce fait et stockent l'état de la reprise de l'activité 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 reprend uniquement l'activité la plus élevée dans l'ordre Z. Les applications ciblant Android 10 peuvent prendre en charge la reprise de plusieurs activités en même temps.

Accès simultané aux caméras

  • Problèmes . Ces problèmes sont également présents dans Android 9 et versions antérieures. Par exemple, une activité en plein écran et reprise peut perdre le focus de la caméra au profit d'une activité suspendue en mode image dans l'image, mais devenir plus exposée avec l'adoption plus large des modes multi-fenêtres et multi-affichages.
    • En raison des modifications apportées à l'état RESUME , les applications peuvent être déconnectées de la caméra même lors de la reprise . Pour résoudre ce problème, les applications doivent gérer une déconnexion de la caméra sans planter. Lorsqu'elles sont déconnectées, les applications reçoivent un rappel déconnecté et tous les appels à l'API commencent à lancer CameraAccessException .
    • resizeableActivity=false ne garantit pas un accès exclusif à la caméra, car d'autres applications utilisant la caméra peuvent être ouvertes sur d'autres écrans.
  • Solutions. Les développeurs doivent inclure une logique lorsqu'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 tenter 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ù la mise au point (et la priorité de la caméra) bascule entre plusieurs activités reprises. Les développeurs d'applications doivent utiliser ces deux rappels pour déterminer le bon moment pour tenter d'accéder à la caméra.

Multi-CV

Dans Android 10, l'état du cycle de vie de l'activité est déterminé par la visibilité et l'ordre Z. Pour garantir que l'état correct après la mise à jour de la visibilité sur une activité et évaluer quel état du cycle de vie est 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 plutôt qu'à un seul emplacement du système. En effet, plusieurs transitions d'activités peuvent être effectuées simultanément dans les modes multi-fenêtres. Pour plus de détails, consultez ActivityStack#mInResumeTopActivity .

Rappel d'activité de reprise supérieure

Après des actions pouvant entraîner un changement d'activité principal (telles que le lancement, la reprise ou la modification de l'ordre Z d'une activité), ActivityStackSupervisor#updateTopResumedActivityIfNeeded() est invoqué. Cette méthode vérifie si l'activité reprise la plus élevée a changé et effectue la mise à jour si nécessaire. Si l'activité de reprise en haut précédente n'a pas libéré l'état de reprise en haut, un message de perte d'état de reprise en haut lui est envoyé et un délai d'attente est planifié côté serveur ( ActivityStackSupervisor#scheduleTopResumedStateLossTimeout() ). Un rapport de l'état de reprise supérieure est envoyé à l'activité suivante après que la précédente ait libéré l'état, ou lorsqu'un délai d'attente a été atteint (voir les utilisations de :

ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()

Un nouvel élément de transaction TopResumedActivityChangeItem a été ajouté pour signaler les changements d'état de reprise aux clients et exploite l'architecture ActivityLifecycler d'Android 9.

L'état de reprise supérieure est stocké côté client, et chaque fois que l'activité passe à RESUMED ou PAUSED , il vérifie également si le rappel onTopResumedActivityChanged() doit être invoqué. Cela permet un certain découplage dans la communication des états du cycle de vie et de l'état de reprise supérieure entre les côtés serveur et client.