Vários currículos

No Android 9 (e versões anteriores), os apps entravam 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 não foi obscurecida e pôde ser interagida pelo usuário. Por exemplo, no modo de múltiplas janelas, diversas atividades podem ser visíveis e receber entradas por 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 superior em pilhas visíveis residem no estado RESUMED . Isso melhora a compatibilidade com os modos Multijanela e MD para aplicativos que usam onPause() em vez de onStop() para interromper a atualização da IU e a interação com o usuário. Isso significa:

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

Figura 1. Multi-currículo em um dispositivo dobrável

Figura 2. Multi-currículo 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 na lateral), a atividade principal não é retomada porque não pode ser focada.
  • No modo picture-in-picture, a atividade não é retomada porque não pode ser focada.
  • 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 somente no estado RESUMED . Antes do Android 10, as atividades também podiam receber entrada no estado PAUSED (por exemplo, tente tocar em ambas as atividades simultaneamente em tela dividida em um dispositivo com Android 9).

Para preservar o sinal retomado das 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 do estado RESUMED para PAUSED sem se tornar a mais alta do sistema. Por exemplo, no modo multijanela. Como esse retorno de chamada é opcional, ele não faz parte do Ciclo de Vida da Atividade e raramente deve ser usado.

A atividade anterior retomada recebe e termina a execução de onTopResumedActivity(false) antes que a próxima atividade retomada receba onTopResumedActivity(true) , a menos que a atividade anterior demore muito para lidar com a chamada do 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

  • Emitir. No Android 9 e versões anteriores, 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 versões anteriores, se duas atividades do mesmo processo forem retomadas, o sistema só retoma a atividade mais alta na ordem Z. Os aplicativos direcionados ao Android 10 podem oferecer 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 versões anteriores. 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 ficar mais exposta com a adoção mais ampla dos modos multijanela e multiexibiçã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 a 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 é uma garantia de acesso exclusivo à câmera, porque outros aplicativos que usam a câmera podem ser abertos em outras telas.
  • 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 reconectar e continuar usando a câmera. Além do retorno de chamada CameraManager#AvailabilityCallback#onCameraAvailable() existente, o Android 10 adicionou CameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged() , que cobre o caso quando 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.

Multi-currículo

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 as atualizações de visibilidade em uma atividade e avaliar qual estado do ciclo de vida é aplicável, invoque o método ActivityRecord#makeActiveIfNeeded() de diferentes locais. No Android 10, ativo significa RESUMED ou PAUSED e funciona apenas nesses dois casos.

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

Retorno de chamada de atividade retomada principal

Após ações que podem resultar em uma alteração de atividade principal (como inicialização de atividade, retomada ou alteração de ordem Z), ActivityStackSupervisor#updateTopResumedActivityIfNeeded() é invocado. Este método verifica se a atividade retomada superior foi alterada e executa a atualização, se necessário. Se a atividade anterior retomada não tiver liberado o estado retomado, uma mensagem de perda de estado retomado será enviada a ela e um tempo limite será agendado no lado do servidor ( ActivityStackSupervisor#scheduleTopResumedStateLossTimeout() ). Um relatório do estado retomado é enviado para a próxima atividade depois que a anterior liberou o estado ou quando o tempo limite foi atingido (veja 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 retomado é armazenado no lado do cliente e cada vez que a atividade transita para RESUMED ou PAUSED , ele também verifica se o retorno de chamada onTopResumedActivityChanged() deve ser invocado. Isso permite certa dissociação na comunicação dos estados do ciclo de vida e do estado retomado entre o servidor e o cliente.