Android destruindo atividades, matando processos

117

Olá, estou me perguntando como o Android está gerenciando a memória e não consigo encontrar uma resposta precisa em qualquer lugar. Vamos supor que eu tenha um aplicativo com 5 atividades na pilha de atividades atual (4 paradas e 1 retomada), não há nenhum serviço conectado. Eu pressiono o botão INÍCIO para que todas as minhas atividades sejam interrompidas. Eu inicio algum outro aplicativo que consome memória e a memória geral do dispositivo está começando a ficar baixa. E a questão é

... O que acontecerá com meu aplicativo?

  1. O sistema pode destruir apenas uma ou algumas das minhas atividades para recuperar a memória?
  2. O sistema interromperá todo o processo do meu aplicativo? Todas as atividades serão bem destruídas?
  3. O que acontecerá quando eu voltar ao meu aplicativo quando ele estiver totalmente desativado? Começará do início (como a primeira inicialização) ou tentará recuperar as atividades ao estado anterior / se sim - é apenas a que está no topo da pilha ou todas elas?

ATUALIZAR:

Antes de fazer esta pergunta, eu vi o ciclo de vida da atividade algumas vezes, mas não tem respostas para minhas perguntas. Fiz alguns testes e tenho algumas respostas. "Parar o processo" no DDMS era uma pista para o teste.

Não testei a resposta para a pergunta 1, mas como o guia diz:

Se uma atividade for pausada ou interrompida, o sistema pode eliminar a atividade da memória pedindo que ela seja concluída ou simplesmente eliminando seu processo.

Parece que uma ou mais atividades podem ser destruídas suavemente (com o método onDestroy) sem interromper o processo. Você simplesmente obterá (onCreate + bundle) quando voltar para eles.

Resposta da pergunta 2:

SIM. Geralmente, o sistema elimina todo o processo, o que significa que todos os dados, incluindo atividades e campos estáticos, são destruídos. Isso NÃO é feito corretamente - você não conseguirá onDestroy ou finialize () para nenhuma de suas atividades pausadas / interrompidas. É por isso que saveInstanceState () é chamado antes do método onPause. onPause é basicamente o último método em que você deve salvar algo porque depois desse método você nunca mais poderá ver onStop ou onDestroy. O sistema pode simplesmente matar o processo, destruindo todos os seus objetos, o que quer que eles contenham e o que quer que estejam fazendo.

Resposta da pergunta 3:

O que acontecerá quando você voltar para um aplicativo desativado?

  • Antes do Android 2.2 - o aplicativo começará do início, com a atividade do iniciador.
  • A partir de 2.2 - o sistema restaurará o estado anterior do aplicativo. O que isso significa? Isso significa que a última atividade visível será recriada (onCreate + bundle). O que acontecerá com a pilha de atividades? Stack está bem, mas todas as atividades nele estão mortas. Cada um deles será recriado (onCreate + bundle) quando você voltar a ele com o botão Voltar. Há mais uma coisa sobre isso:

Normalmente, o sistema limpa uma tarefa (remove todas as atividades da pilha acima da atividade raiz) em certas situações quando o usuário seleciona novamente essa tarefa na tela inicial. Normalmente, isso é feito se o usuário não visita a tarefa por um determinado período de tempo, como 30 minutos.

Conclusão?

  1. Não pense que lidar com problemas de rotação de atividades pode ser resolvido pelo android: configChanges = "idance ". Ao fazer isso, você terá muitos outros problemas dos quais nem mesmo está ciente.
  2. Teste seu aplicativo com DDMS - botão Parar processo. Veja isso
  3. Tenha cuidado ao usar variáveis ​​estáticas. Não pense que quando você os inicializou na atividade 1 - você os terá inicializado na atividade 2. O único lugar seguro para inicializar a estática global seria a classe de aplicativo.
  4. Lembre-se de que você nunca verá onStop ou onDestroy. Feche arquivos / bancos de dados, pare os downloaders em onPause. Quando você quiser que o aplicativo faça algo no BG - use o serviço de primeiro plano.

Seria isso ... Espero ter ajudado com meu ensaio :)

Marca
fonte
Para sua suposição, essas 5 atividades vêm de um mesmo aplicativo ou de vários aplicativos diferentes?
dumbfingers de
1
"Eu tenho um aplicativo com 5 atividades na pilha de atividades atual" Claro que todos eles são do meu único aplicativo de processo.
Marcos
4
Obrigado, essa foi exatamente a minha pergunta também ... Sua pergunta e as respostas me ajudaram bastante.
craigrs84
@Mark: Este problema está resolvido agora? Como se for?
Ameer Moaaviah

Respostas:

30

Primeiro, dê uma olhada nisso:

img1

onPause () Chamado quando o sistema está prestes a retomar uma atividade anterior. Isso é normalmente usado para confirmar alterações não salvas em dados persistentes, parar animações e outras coisas que podem estar consumindo CPU, etc. As implementações desse método devem ser muito rápidas porque a próxima atividade não será retomada até que esse método retorne. Seguido por onResume () se a atividade retornar para a frente, ou onStop () se se tornar invisível para o usuário.

onStop () Chamado quando a atividade não está mais visível para o usuário, porque outra atividade foi retomada e está cobrindo esta. Isso pode acontecer porque uma nova atividade está sendo iniciada, uma existente está sendo trazida para a frente desta ou esta está sendo destruída. Seguido por onRestart () se esta atividade está voltando para interagir com o usuário, ou onDestroy () se esta atividade está indo embora.

Então, quando você pressiona o botão "HOME" no seu dispositivo, sua atividade de primeiro plano atual é colocada em onPause()seguida onStop(), os outros 4 devem permaneceronStop()

De acordo com os documentos do Google:

  • Se for uma atividade em primeiro plano da tela (no topo da pilha), ela está ativa ou em execução.
  • Se uma atividade perdeu o foco, mas ainda está visível (ou seja, uma nova atividade não em tamanho real ou transparente tem foco no topo de sua atividade), ela é pausada. Uma atividade pausada está completamente ativa (ela mantém todas as informações de estado e membro e permanece anexada ao gerenciador de janelas), mas pode ser eliminada pelo sistema em situações de memória extremamente baixa.
  • Se uma atividade for completamente obscurecida por outra atividade, ela será interrompida. Ele ainda retém todas as informações de estado e membro, no entanto, não é mais visível para o usuário, portanto, sua janela fica oculta e, com frequência, será eliminado pelo sistema quando a memória for necessária em outro lugar.
  • Se uma atividade for pausada ou interrompida, o sistema pode eliminar a atividade da memória pedindo que ela seja concluída ou simplesmente eliminando seu processo. Quando for exibido novamente para o usuário, ele deve ser completamente reiniciado e restaurado ao seu estado anterior.

E, para o ciclo de vida do processo:

Ciclo de vida do processo 3. Uma atividade em segundo plano (uma atividade que não é visível para o usuário e foi pausada) não é mais crítica, então o sistema pode encerrar com segurança seu processo para recuperar memória para outros processos em primeiro plano ou visíveis. Se seu processo precisar ser eliminado, quando o usuário navegar de volta para a atividade (tornando-o visível na tela novamente), seu método onCreate (Bundle) será chamado com o savedInstanceState que ele havia fornecido anteriormente em onSaveInstanceState (Bundle) para que pode reiniciar-se no mesmo estado em que o usuário o deixou pela última vez.

Todas as citações acima vêm de: Referência dos desenvolvedores Android: Atividade

É confirmado que o sistema pode destruir atividades não ativas e reciclar memórias quando você inicia alguns aplicativos que consomem memória. E você pode implementar como: isFinishing()em sua atividade e, em seguida, usando o botão "kill" no DDMS para detectar quais das suas atividades estão sendo descartadas pelo sistema. Mas acho que o sistema destruirá o mais antigo primeiro. No entanto, não adianta manter outras atividades quando a "Atividade de inicialização" foi reciclada.

ATUALIZAR

Aqui estão algumas opiniões que encontrei aqui :

Estado parado

Quando uma atividade não está visível, mas ainda está na memória, dizemos que ela está parada. A atividade interrompida pode ser trazida de volta para a frente para se tornar uma atividade de corrida novamente. Ou pode ser destruído e removido da memória.

O sistema mantém as atividades em um estado interrompido porque é provável que o usuário ainda deseje voltar a essas atividades em breve, e reiniciar uma atividade interrompida é muito mais barato do que iniciar uma atividade do zero. Isso porque já temos todos os objetos carregados na memória e simplesmente temos que trazê-los para o primeiro plano.

As atividades interrompidas podem ser removidas da memória a qualquer momento.

halteres
fonte
4
A documentação é bastante confusa sobre este assunto, no entanto, apenas um processo inteiro pode ser eliminado, não componentes individuais (atividades, serviços, etc.). Consulte: stackoverflow.com/questions/7536988/…
greg7gkb
Esta pergunta deve ser atualizada com as informações no link do comentário @ greg7gkb, é enganoso
Luke De Feo
1

O sistema pode destruir apenas uma ou algumas das minhas atividades para recuperar a memória?

Sim. O Android elimina atividades que estão sendo executadas em segundo plano quando há necessidade de memória. Matar um ou todos pode depender de algumas condições. Por exemplo, pausado ou interrompido pode fazer o android matar uma atividade ou um processo em si. Aqui, em Ciclo de vida da atividade, você pode obter os pontos abaixo. Eu recomendo que você percorra essa página completamente. Com certeza vai tirar suas dúvidas.

Se uma atividade perdeu o foco, mas ainda está visível (ou seja, uma nova atividade não em tamanho real ou transparente tem foco no topo de sua atividade), ela é pausada. Uma atividade pausada está completamente ativa (ela mantém todas as informações de estado e membro e permanece anexada ao gerenciador de janelas), mas pode ser eliminada pelo sistema em situações de memória extremamente baixa.

Se uma atividade for completamente obscurecida por outra atividade, ela será interrompida. Ele ainda retém todas as informações de estado e membro, no entanto, não é mais visível para o usuário, portanto, sua janela fica oculta e, com frequência, será eliminado pelo sistema quando a memória for necessária em outro lugar.

Se uma atividade for pausada ou interrompida, o sistema pode eliminar a atividade da memória pedindo que ela seja concluída ou simplesmente eliminando seu processo. Quando for exibido novamente para o usuário, ele deve ser completamente reiniciado e restaurado ao seu estado anterior.


O sistema interromperá todo o processo do meu aplicativo? Todas as atividades serão bem destruídas?

A atividade pertence a um indivíduo, enquanto o processo pertence a um grupo de atividades. Observe o terceiro ponto acima novamente, ele mata o processo conforme mencionado.


O que acontecerá quando eu voltar ao meu aplicativo quando ele estiver totalmente desativado?

É semelhante ao reiniciar. Novamente, o terceiro ponto lhe dará algumas respostas comoWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Obtenha mais informações sobre coisas relacionadas à memória aqui .

Editar:
todas as atividades em um aplicativo são executadas em um único processo. Portanto, quando um processo é encerrado, todas as atividades, independentemente de 5 ou 10, serão encerradas, ou seja, reiniciadas. A reinicialização fará com que seu aplicativo seja iniciado do início, sem estados salvos.

Vinay
fonte
2
Eu vi o Activity Lifecycle pelo menos 5 vezes, mas não responde às minhas perguntas. O que você disse significaria quando o processo do meu aplicativo fosse encerrado - quando eu voltar ao aplicativo, ele será restaurado ao estado anterior. Então, quando eu tinha 5 atividades interrompidas ... todas elas morreram (onDestroy invocado) quando o processo foi encerrado? Quando voltei ao meu aplicativo, todas as atividades foram restauradas (onCreate + bundle) ou apenas a que estava no topo da pilha (visível para o usuário)?
Marcos
1
Todas as atividades em um aplicativo são executadas em um único processo. Portanto, quando um processo é encerrado, todas as atividades, independentemente de 5 ou 10, serão encerradas, ou seja, reiniciadas. Reiniciar fará com que seu aplicativo seja iniciado do início, sem estados salvos.
Vinay
1
Quase verdade, mas não para 2.2 e superior. Veja meu UPDATE no topo da página.
Marcos
1
Não, isso não é verdade e nunca foi verdade. É confuso com base na documentação, mas consulte: stackoverflow.com/questions/7536988/…
greg7gkb
2
@JJPA Android não pode destruir atividades únicas para recuperar memória, apenas destrói processos. Veja esta resposta de Dianne Hackbor, membro da equipe principal do Android envolvido na implementação do "assassino sem memória": stackoverflow.com/a/7576275/1290264 .
bcorso