Vários currículos

No Android 9 (e inferior), os aplicativos foram inseridos no estado PAUSED quando:

  • Uma nova atividade translúcida foi lançada na parte superior do aplicativo, enquanto o aplicativo ainda estava visível (e, portanto, não foi interrompido).
  • A atividade perdeu o foco, mas foi desobstruída e pode ser interagida pelo usuário. Por exemplo, no modo de várias janelas, várias atividades podem ser visíveis e receber entrada de toque simultaneamente.

Essas situações diferem na quantidade de pausa que um aplicativo deve fazer, mas não podem ser diferenciadas no nível do aplicativo.

No Android 10, todas as atividades com foco principal em pilhas visíveis residem no estado RESUMED . Isso melhora a compatibilidade com os modos Multi-Window e MD para aplicativos que usam onPause() em vez de onStop() para interromper a atualização da interface do usuário e a interação com o usuário. Isso significa:

  • Ambas as atividades em tela dividida são retomadas.
  • Todas as atividades visíveis no topo no modo de janela de formato livre são retomadas.
  • As atividades em várias telas podem ser retomadas ao mesmo tempo.

Figura 1. Currículo múltiplo em um dispositivo dobrável

Figura 2. Currículo múltiplo no modo desktop

As atividades podem residir no estado PAUSED quando não podem ser focadas ou estão parcialmente ocluídas, como:

  • Em uma tela dividida minimizada (com o iniciador ao lado), a atividade principal não é retomada porque não é focalizável.
  • No modo picture-in-picture, a atividade não é retomada porque não é focalizável.
  • Quando as atividades são cobertas por outras atividades transparentes na mesma pilha.

Essa abordagem indica aos aplicativos que uma atividade pode receber entrada de um usuário apenas no estado RESUMED . Antes do Android 10, as atividades também podiam receber entrada no estado PAUSED (por exemplo, tente tocar as duas atividades em tela dividida simultaneamente em um dispositivo com Android 9).

Para preservar o sinal retomado de versões anteriores do Android (e para comunicar quando os aplicativos devem obter acesso a recursos de acesso exclusivo ou singleton), o Android 10 inclui um novo retorno de chamada:

Activity#onTopResumedActivityChanged(boolean onTop)

Quando invocado, esse retorno de chamada é chamado entre Activity#onResume() e Activity#onPause() . Esse retorno de chamada é opcional e pode ser ignorado, portanto, uma atividade pode passar de um estado RESUMED para PAUSED sem se tornar a mais alta do sistema. Por exemplo, no modo multi-janela. Como esse retorno de chamada é opcional, ele não faz parte do Ciclo de Vida da Atividade e deve ser usado raramente.

A atividade retomada principal anterior recebe e termina a execução de onTopResumedActivity(false) antes que a próxima atividade retomada principal receba onTopResumedActivity(true) , a menos que a atividade anterior leve muito tempo para lidar com a chamada de método e atinja o tempo limite de 500 ms.

Compatibilidade

Para manter a compatibilidade ao implementar vários currículos, considere estas soluções.

Várias atividades retomadas em um processo de aplicativo

  • Questão. No Android 9 e inferior, apenas uma atividade no sistema é retomada por vez. Todas as transições entre atividades envolvem pausar uma atividade antes de retomar outra. Alguns aplicativos e estruturas (como Flutter ou LocalActivityManager do Android) usam esse fato e armazenam o estado sobre a atividade retomada em singletons.
  • Solução. No Android 9 e inferior, se duas atividades do mesmo processo forem retomadas, o sistema retomará apenas a atividade mais alta na ordem Z. Os aplicativos direcionados ao Android 10 podem dar suporte à retomada de várias atividades ao mesmo tempo.

Acesso simultâneo à câmera

  • Problemas . Esses problemas também estão presentes no Android 9 e inferior. Por exemplo, uma atividade em tela cheia e retomada pode perder o foco da câmera para uma atividade pausada na parte superior no modo picture-in-picture, mas fica mais exposta com a adoção mais ampla dos modos multi-janela e multi-exibição.
    • Devido às alterações feitas no estado RESUME , os aplicativos podem ser desconectados da câmera mesmo durante a retomada . Para resolver isso, os aplicativos devem lidar com uma desconexão da câmera sem travar. Quando desconectados, os aplicativos recebem um retorno de chamada desconectado e todas as chamadas para a API começam a gerar CameraAccessException .
    • resizeableActivity=false não é garantia de acesso exclusivo à câmera, pois outros aplicativos que usam a câmera podem ser abertos em outros monitores.
  • Soluções. Os desenvolvedores devem incluir lógica para quando um aplicativo for desconectado da câmera. Se um aplicativo for desconectado da câmera, ele deverá observar os retornos de chamada de disponibilidade da câmera para tentar se reconectar e continuar o uso da câmera. Além do retorno de chamada CameraManager#AvailabilityCallback#onCameraAvailable() existente, o Android 10 adicionou CameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged() , que abrange o caso em que o foco (e a prioridade da câmera) alterna entre várias atividades retomadas. Os desenvolvedores de aplicativos devem usar esses dois retornos de chamada para determinar um bom momento para tentar obter acesso à câmera.

Vários currículos

No Android 10, o estado do ciclo de vida da atividade é determinado pela visibilidade e pela ordem Z. Para garantir que o estado correto após a visibilidade seja atualizado em uma atividade e avaliar qual estado do ciclo de vida é aplicável, invoque o método ActivityRecord#makeActiveIfNeeded() de locais diferentes. No Android 10, ativo significa RESUMED ou PAUSED e funciona apenas nessas duas instâncias.

No Android 10, a retomada de uma atividade é rastreada separadamente em cada pilha, e não em um único local no sistema. Isso ocorre porque várias transições de atividade podem ser executadas simultaneamente em modos de várias janelas. Para obter detalhes, consulte ActivityStack#mInResumeTopActivity .

Retorno de chamada de atividade mais retomada

Após ações que podem resultar em uma alteração de atividade principal (como início de atividade, retomada ou alteração de ordem Z), ActivityStackSupervisor#updateTopResumedActivityIfNeeded() é invocado. Esse método verifica se a atividade retomada mais alta foi alterada e executa a atualização, se necessário. Se a atividade anterior com a maior retomada não tiver liberado o estado com a maior retomada, uma mensagem de perda de estado com a maior retomada será enviada a ela e um tempo limite será agendado no lado do servidor ( ActivityStackSupervisor#scheduleTopResumedStateLossTimeout() ). Um relatório do estado mais retomado é enviado para a próxima atividade depois que a anterior liberou o estado ou quando um tempo limite foi atingido (consulte os usos de:

ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()

Um novo item de transação TopResumedActivityChangeItem foi adicionado para relatar as principais alterações de estado retomadas aos clientes e aproveita a arquitetura ActivityLifecycler do Android 9.

O estado de retomada superior é armazenado no lado do cliente e, cada vez que a atividade passa para RESUMED ou PAUSED , ela também verifica se o retorno de chamada onTopResumedActivityChanged() deve ser invocado. Isso permite certo desacoplamento na comunicação dos estados do ciclo de vida e o estado de retomada superior entre os lados do servidor e do cliente.