O Android interromperá um processo se estiver em segundo plano e o sistema operacional decidir que precisa dos recursos (RAM, CPU, etc.). Eu preciso ser capaz de simular esse comportamento durante o teste para garantir que meu aplicativo esteja se comportando corretamente. Quero poder fazer isso de maneira automatizada, para poder testar se o aplicativo se comporta corretamente sempre que isso acontece, o que significa que terei que testá-lo em todas as atividades, etc.
Eu sei como matar meu processo. Esse não é o problema. O problema é que quando eu matar meu processo (usando DDMS, adb shell kill
, Process.killProcess()
, etc.) Android não reiniciá-lo da mesma forma que seria se o sistema operacional Android tinha matado ele próprio.
Se o sistema operacional Android concluir o processo (devido a requisitos de recursos), quando o usuário retornar ao aplicativo, o Android recriará o processo e, em seguida, recriará a atividade principal na pilha de atividades (chamada onCreate()
).
Por outro lado, se eu matar o processo, o Android assume que a atividade na parte superior da pilha de atividades foi mal comportada ; portanto, ela recria automaticamente o processo e remove a atividade principal da pilha de atividades e recria a atividade que estava por baixo a atividade principal (chamando onCreate () `). Este não é o comportamento que eu quero. Eu quero o mesmo comportamento de quando o Android mata o processo.
Apenas para explicar pictoricamente, se minha pilha de atividades estiver assim:
ActivityA -> ActivityB -> ActivityC -> ActivityD
Se o Android matar o processo e o usuário retornar ao aplicativo, o Android recria o processo e cria o ActivityD.
Se eu matar o processo, o Android recria o processo e cria o ActivityC.
Respostas:
A melhor maneira de testar isso para mim foi fazer o seguinte:
Terminate Application
na janela Logcat no Android Studio (isso interromperá o processo do aplicativo, selecione o dispositivo e o processo nas listas suspensas do Logcat na parte superior)Em alguns dispositivos, você também pode voltar ao aplicativo (ActivityD) com Aplicativos -> ícone do iniciador, mas em outros dispositivos, ele iniciará o ActivityA.
Isto é o que os documentos do Android estão dizendo sobre isso:
fonte
<activity>
tag no manifesto.Isso parece funcionar para mim:
Isso é diferente do
adb shell kill
mencionado pelo OP.Observe que a ajuda para o
am kill
comando diz:Portanto, não matará o processo se estiver em primeiro plano. Isso parece funcionar como o OP queria, pois se eu sair do meu aplicativo, executá-
adb shell am kill <package_name>
lo matará o aplicativo (confirmei isso usandops
o dispositivo). Então, se eu voltar ao aplicativo, volto à atividade em que estava anteriormente - ou seja, no exemplo do OP, o processo é recriado e cria ActivityD (em vez de ActivityC como a maioria dos outros métodos de matar parece desencadear).Desculpe, estou dois anos atrasado para o OP, mas espero que outros achem isso útil.
fonte
adb shell am force-stop
. O último também removerá qualquer Intendente pendente relacionado ao seu aplicativo (como Notificações), enquanto o primeiro não.am kill
.ps
mostra meu aplicativoOutro método, provavelmente um que pode ser script, pois não requer DDMS:
Configuração única: vá para Opções do desenvolvedor, selecione Configuração do limite do processo em segundo plano, altere o valor de 'Limite padrão' para 'Nenhum processo em segundo plano'.
Quando você precisar reiniciar o processo, pressione o botão home. O processo será interrompido (você pode verificar no logcat / Android Monitor no studio - o processo será marcado como [MORTO]). Em seguida, volte ao aplicativo usando o alternador de tarefas.
fonte
Esta pergunta é antiga, mas existe uma resposta para essa pergunta que não requer adb, Android Studio etc. O único requisito é a API 23 ou mais recente.
Para simular a reinicialização do aplicativo pelo SO, vá para as configurações do aplicativo enquanto o aplicativo estiver em execução, desative (então você pode habilitar) uma permissão e retorne o aplicativo a partir de aplicativos recentes. Quando a permissão está desativada, o sistema operacional mata o aplicativo, mas mantém os estados da instância salvos. Quando o usuário retorna o aplicativo, ele e a última atividade (com estado salvo) são recriados.
O método 'Nenhum processo em segundo plano' às vezes causa o mesmo comportamento, mas nem sempre. Por exemplo, se o aplicativo estiver executando um serviço em segundo plano, "Nenhum processo em segundo plano" não fará nada. Mas o aplicativo pode ser morto pelo sistema, incluindo seus serviços. O método de permissão funciona mesmo se o aplicativo tiver um serviço.
Exemplo:
Nosso aplicativo tem duas atividades. ActivityA é a atividade principal iniciada no iniciador. ActivityB é iniciado a partir de ActivityA. Mostrarei apenas os métodos onCreate, onStart, onStop, onDestroy. O Android chama onSaveInstanceState sempre antes de chamar onStop, porque uma atividade que está no estado de parada pode ser eliminada pelo sistema. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
Método de permissão:
Eu quero comparar outros métodos mencionados nas outras respostas.
Não mantenha atividades: isso não mata o aplicativo.
Forçar método de parada: Não armazena estados de instância salvos
fonte
Service
morto várias vezes. Mesmo se o sistema não estiver com pouca memória. A maioria dos fabricantes de dispositivos criou suas próprias "otimizações" e "melhorias" no sistema operacional Android para economizar energia da bateria. Muitos dispositivos têm "assassinos" muito mais agressivos do que o Android padrão.Estou muito atrasado para a festa e vários antes de mim deram a mesma resposta correta, mas para simplificar para quem vem depois de mim, basta pressionar o botão home e executar este comando:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
O aplicativo não perde o estado e, por minha própria experiência, isso funciona da mesma maneira que o sistema operacional matou o aplicativo em segundo plano. Isso funciona apenas para aplicativos de depuração criados
fonte
'grep' is not recognized as an internal or external command, operable program or batch file.
run-as <package name> kill 7379
, mas me colocou na atividade anterior, não na atividade em que estava quando pressionei o botão home.É assim que você faz no Android Studio.
fonte
Android Monitor - Monitors
. Deve ser algo de que eles se livraram. Estou no v 3.2.1Coloque o aplicativo em segundo plano com o botão HOME
Selecione seu processo no modo "Logcat" no Android Studio e clique em Finalizar aplicativo no canto inferior esquerdo
Agora inicie seu aplicativo a partir do iniciador no dispositivo Android
EDIT: De acordo com a internet, o seguinte também funciona:
EDITAR no futuro: algo a ser observado, houve uma alteração no Android Studio 4.0, se você usar
Run
do AS,Terminate
emitirá aForce Stop
.No entanto, se você iniciar a partir do iniciador posteriormente, e então tentar simulá-lo dessa maneira, obterá os resultados desejados (comportamento de pouca memória).
fonte
the behaviour is not the same as what happens when Android kills the process
sim, éVocê pode executar as próximas etapas para reproduzir o comportamento procurado:
fonte
Nas opções do desenvolvedor em Configurações, selecione 'Não manter atividades', que destruirá as atividades assim que você as afastar.
Nota: De acordo com um comentário útil abaixo, use-o somente se você não se importar com a remoção de valores estáticos.
fonte
Pressione o botão Início e coloque o aplicativo em segundo plano primeiro. Em seguida, pare ou interrompa o processo do DDMS ou ADB.
fonte
Você também pode conectar-se ao seu dispositivo / emulador a partir do terminal com
adb shell
, em seguida, obterps | grep <your_package_name
e executar o PID do seu processokill -9 <pid>
. Em seguida, abra seu aplicativo minimizado no seletor de aplicativos recentes e ele reiniciará a última atividadefonte
A raiz do seu problema parece ser que você
Activity
está em primeiro plano quando você mata o processo.Você pode observar isso pressionando stop no DDMS quando
Activity
estiver visível (acontece exatamente o que você descreve) e comparando com pressionando stop depois de casa e depois retornando ao aplicativo.Apenas certifique-se de
moveTaskToBack(true)
alguma forma em seus testes.fonte
Não sei se essa é a resposta que você está procurando, é mais como um pensamento lógico.
Eu não acho que você possa realmente fazer um teste totalmente automatizado, a única maneira de simulá-lo, será recriá-lo, o AKA tem tantas atividades que o Android matará seu aplicativo.
Portanto, minha ideia ou sugestão é criar outro aplicativo pequeno, que continue aparecendo novas atividades, até o Android ficar sem memória e começar a matar o processo em segundo plano.
Algo na linha:
Iniciar atividade i -> Verifique o processo em execução se o aplicativo estiver na lista, incremente i e reinicie o loop sem fechar a atividade atual, caso contrário -> diminua ie feche a atividade atual, volte para a anterior e verifique novamente ...
fonte
Quando o processo do aplicativo morre, o Android passa pelos registros de atividades (as entradas representam atividades na pilha do histórico) e decide quais manter no histórico e quais remover dele.
Um dos pontos principais aqui é o
ActivityRecord
campo chamadohaveState
, que os engenheiros do Android Framework descrevem como "chegamos ao último estado de atividade?".Por padrão, o Android considera que a atividade tem um estado. A atividade se torna sem estado quando o aplicativo relata ao serviço do gerenciador de tarefas que a atividade foi retomada e isso é válida até que o aplicativo notifique a estrutura de que a atividade entrou no estado Parado. Em palavras simples, o
haveState
valorfalse
entre atividadeonResume()
é chamado eonStop()
ouonSaveInstanceState()
é chamado, dependendo da versão de destino do aplicativo.Nesse caso, ActivityD não possui
android:stateNotNeeded="true"
atributo no manifesto do aplicativo e está em execução no primeiro plano; portanto, o Android o remove do histórico, pois o sistema não obteve seu último estado.Como foi mencionado várias vezes, você pode simplesmente mover o aplicativo para o segundo plano, para que a atividade principal na pilha traseira da atividade salve seu estado e, depois disso, você pode eliminar o processo do aplicativo através do Android Debug Bridge, Android Studio ou usando o Propriedade Limite de Processos em Segundo Plano nas Opções do Desenvolvedor. Depois disso, sua atividade recente será recriada com sucesso.
Apesar disso, há também outra maneira simples de testar o cenário de morte do processo de aplicativo. Sabendo tudo o que foi descrito acima e o fato de que, se você iniciar a nova ActivityE a partir da ActivityD atualmente em execução, o
onStop()
retorno de chamada da ActivityD será invocado somente após oonResume()
método ActivityE , você poderá executar o seguinte truque.Em seguida, basta iniciar
TerminatorActivity
quando você deseja matar o aplicativo.No final, existe uma ferramenta leve que simplifica o teste da morte do processo de aplicação, chamada Venom .
fonte