Mantendo o estado do aplicativo Android usando AlwaysRetainTaskState e lauchMode
-
20-09-2019 - |
Pergunta
No meu aplicativo Android, tenho uma atividade principal que serve como ponto de entrada para meu aplicativo, que está configurada em meu arquivo de manifesto assim:
<activity android:name=".Main"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Portanto, para um caso de uso específico, digamos que um usuário inicie o aplicativo na tela inicial clicando no ícone dentro do inicializador de aplicativos.Após iniciar o aplicativo, o usuário navega da atividade Principal para a atividade A e finalmente para a atividade B.Nesse ponto, o usuário decide verificar seu Facebook, então clica no botão home para colocar meu aplicativo em segundo plano e inicia o aplicativo do Facebook.
Depois de verificar seu Facebook, o usuário deseja retornar ao meu aplicativo, então pressiona a tecla home e inicia o aplicativo a partir do inicializador de aplicativos (assim como fez na primeira vez que foi iniciado).
Quando um usuário retorna ao meu aplicativo, quero que o aplicativo retorne à última atividade em que o usuário estava quando o aplicativo foi colocado em segundo plano, que neste caso é a atividade B.No arquivo de manifesto, configurei AlwaysRetainTaskState=true para garantir que o sistema operacional não interrompa as atividades do meu aplicativo.
Agora a minha pergunta:como obtenho o comportamento que descrevi acima?Sempre que clico no ícone do meu aplicativo, ele sempre inicia na atividade Principal, não importa o que aconteça.Acho que isso se deve ao atributo category.LAUNCHER.Eu tentei Android:launchMode=singleTask, mas não fez diferença;sempre começa em Main.
Se alguém pudesse esclarecer filtros de intenções, modos de inicialização e tarefas, seria ótimo!
Solução
Eu resolvi isso adicionando o sem tela DispatcherActivity
e tornando -o padrão (usando o mesmo filtro de intenção). Em seu onCreate
Método que você cria e chama de intenção com base em algum padrão razoável (sua atividade principal, por exemplo) ou com base em algum token salvo que identifica qual atividade deve ser iniciada. Esse token é salvo/atualizado em onStop
Método de qualquer atividade que você deseja chamar de reinicialização. Você pode salvar esse token em preferências.
O racional aqui é que a última atividade visível será executada no método Onstop quando interrompida.
Palavra de cautela aqui: Implementei esse padrão e funcionou razoavelmente bem. No entanto, parece não jogar muito bem com a história e, finalmente, eu desisti e puxei esse código. Ninguém reclamou até agora.
Outras dicas
Para sua informação singleTask
não é o que você quer, pois inicia uma nova tarefa:
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Como você está lançando a atividade B? Algum modos de lançamento não padrão ou sinalizadores de intenção?
Para quem vem aqui com problemas parecidos, encontrei algo estranho que pode ser o que vocês estão vendo...talvez.
Digamos que eu tenha um aplicativo com atividades A -> B -> C etc.Eu estava tendo problemas com meu aplicativo sempre "retomando" para A se ele fosse iniciado na lista de aplicativos, também conhecido como iniciador.Retomar a partir da tela "reenviado" (pressionar longamente a página inicial) exibiria um comportamento de retomada correto (retomar para B ou C conforme o esperado).Meu manifesto não foi nada especial, sempreRetainTaskState="true" definido em minha atividade raiz e o modo de inicialização é o padrão (padrão).
Eu estava carregando o apk no meu telefone por meio de um site.Depois de baixar e instalar, Eu pressionaria "Abrir" para iniciar o aplicativo imediatamente.Por algum motivo (depois de desinstalar o aplicativo) cansei de baixar novamente, instalar, mas depois pressionou o botão "Concluído" em vez disso.Em seguida, iniciar o aplicativo a partir da lista inicializador/"todos os aplicativos" tem o mesmo comportamento de retomada dos recentes - em outras palavras, meus problemas estavam sendo causados de alguma forma por causa do processo de instalação ao clicar em "Abrir" em vez de "Concluído".
Verifiquei esta "solução" na API10 (2.3.5) e API15 (4.0.4)