No Android 9 e em versões anteriores, os apps entravam no estado PAUSED
quando:
- Uma nova atividade translúcida iniciada sobre o app enquanto ele ainda estava visível (e, portanto, não foi interrompido).
- A atividade perdeu o foco, mas não foi obscurecida e podia ser interagida pelo usuário. Por exemplo, no modo de várias janelas, várias atividades podem ficar visíveis e receber entrada por toque simultaneamente.
Essas situações diferem na quantidade de pausas que um app precisa fazer, mas não podem ser diferenciadas no nível do app.
No Android 10, todas as atividades com foco principal em pilhas visíveis estão no
estado RESUMED
. Isso melhora a compatibilidade com os modos Multi-Window e MD para apps que usam onPause()
em vez de onStop()
para interromper a atualização da interface e a interação com o usuário. Isso significa que:
- As duas atividades em tela dividida são retomadas.
- Todas as atividades mais visíveis no modo de janelas de formato livre são retomadas.
- As atividades em várias telas podem ser retomadas ao mesmo tempo.
Figura 1. Retomada múltipla em um dispositivo dobrável
Figura 2. Retomada múltipla no modo de computador
As atividades podem ficar no estado PAUSED
quando não podem ser focalizadas ou estão parcialmente ocultas, como:
- Em uma tela dividida minimizada (com o iniciador na lateral), a atividade principal não é retomada porque não pode ser focalizada.
- No modo picture-in-picture, a atividade não é retomada porque não pode ser focalizada.
- Quando as atividades são cobertas por outras atividades transparentes na mesma pilha.
Essa abordagem indica aos apps que uma atividade só pode receber entrada de um
usuário no estado RESUMED
. Antes do Android 10,
as atividades também podiam receber entrada no estado PAUSED
. Por exemplo, tente tocar
nas duas atividades em tela dividida simultaneamente em um dispositivo com Android 9.
Para preservar o indicador retomado de versões anteriores do Android (e para comunicar quando os apps devem obter acesso a recursos de acesso exclusivo ou singleton), o Android 10 inclui um novo callback:
Activity#onTopResumedActivityChanged(boolean onTop)
Quando invocado, esse callback é chamado entre Activity#onResume()
e Activity#onPause()
. Esse callback é opcional e pode ser ignorado.
Assim, uma atividade pode passar de um estado RESUMED
para um PAUSED
sem se tornar a mais importante no sistema. Por exemplo, no modo de várias janelas.
Como esse callback é opcional, ele não faz parte do ciclo de vida da atividade e deve ser usado raramente.
A atividade anterior no topo e retomada recebe e conclui a execução de
onTopResumedActivity(false)
antes que a próxima atividade no topo e retomada
receba onTopResumedActivity(true)
, a menos que a atividade anterior
demore muito para processar a chamada de método e atinja o tempo limite de 500 ms.
Compatibilidade
Para manter a compatibilidade ao implementar a retomada múltipla, considere estas soluções.
Várias atividades retomadas em um processo de app
- Problema. 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 apps e frameworks (como o Flutter ou o LocalActivityManager do Android) usam esse fato e armazenam o estado da atividade retomada em singletons.
- Solução. No Android 9 e versões anteriores, se duas atividades do mesmo processo forem retomadas, o sistema só vai retomar a atividade que estiver mais acima na ordem Z. Os apps destinados ao Android 10 podem oferecer suporte a várias atividades retomadas ao mesmo tempo.
Acesso simultâneo à câmera
- Problemas. Esses problemas também estão presentes no Android 9 e
em 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 de cima no modo picture-in-picture, mas ficar mais exposta com
a adoção mais ampla dos modos de várias janelas e várias telas.
- Devido a mudanças feitas no estado
RESUME
, os apps podem ser desconectados da câmera mesmo quando retomados. Para resolver isso, os apps precisam processar uma desconexão da câmera sem falhar. Quando desconectados, os apps recebem um callback de desconexão, e todas as chamadas para a API começam a gerarCameraAccessException
. resizeableActivity=false
não garante o acesso exclusivo à câmera, já que outros apps que usam a câmera podem ser abertos em outras telas.
- Devido a mudanças feitas no estado
- Soluções. Os desenvolvedores precisam incluir lógica para quando um app
é desconectado da câmera. Se um app for desconectado da câmera, ele
precisará monitorar os callbacks de disponibilidade da câmera para tentar se reconectar e continuar
usando a câmera. Além do callback
CameraManager#AvailabilityCallback#onCameraAvailable()
atual, o Android 10 adicionouCameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged()
, que abrange o caso em que o foco (e a prioridade da câmera) muda entre várias atividades retomadas. Os desenvolvedores de apps precisam usar os dois callbacks para determinar um bom momento para tentar acessar a câmera.
Retomada múltipla
No Android 10, o estado do ciclo de vida da atividade é determinado pela visibilidade e pela ordem Z. Para garantir o estado correto após 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 nessas duas instâncias.
No Android 10, a retomada de uma atividade é rastreada separadamente em cada pilha, em vez de em um único local no sistema. Isso acontece porque várias
transições de atividade podem ser realizadas simultaneamente em modos de várias janelas. Para
mais detalhes, consulte ActivityStack#mInResumeTopActivity
.
Callback da atividade retomada principal
Depois de ações que podem resultar em uma mudança na atividade principal (como
início, retomada ou mudança na ordem Z),
ActivityStackSupervisor#updateTopResumedActivityIfNeeded()
é invocado. Esse
método verifica se a atividade retomada mais importante mudou e faz a atualização, se
necessário. Se a atividade anterior em primeiro plano não tiver liberado o estado de primeiro plano, uma mensagem de perda de estado de primeiro plano será enviada a ela, e um tempo limite será programado no lado do servidor (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()
). Um relatório do estado de primeiro plano será enviado para a próxima atividade depois que a anterior liberar o estado ou quando um tempo limite for atingido. Consulte os usos de:
ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()
Um novo item de transação TopResumedActivityChangeItem
foi adicionado para informar as principais mudanças de estado retomadas aos clientes e aproveita a arquitetura ActivityLifecycler
do Android 9.
O estado de retomada da parte superior é armazenado no lado do cliente, e cada vez que a
atividade faz a transição para RESUMED
ou PAUSED
, ela também
verifica se o callback onTopResumedActivityChanged()
deve ser
invocado. Isso permite um certo desacoplamento na comunicação de estados do ciclo de vida
e o estado de retomada principal entre os lados do servidor e do cliente.