Ciclo de vida do objeto estático do Android

101

Estou criando um aplicativo de pesquisa de eventos, nós definimos os critérios de pesquisa de uma tela para preencher em outra tela, então o usuário pode editar os critérios de pesquisa da 3ª tela e ir para a 4ª tela.

Para realizar a tarefa acima, estou usando um objeto estático que lembra os valores ao redor do aplicativo e não preciso fazer nada extra.

Mas estou com medo se sobre o ciclo de vida do objeto estático no Android, se houver pouca memória no Android, exclua objetos estáticos ??

Como o Android suporta multitarefa, se o usuário mudar para outro aplicativo e quando o usuário voltar, o aplicativo começa a agir maluco, o objeto estático é removido quando ele multi-tarefa ?? qualquer ideia ?? e também sugerir segurar um objeto estático através do método singleton é a melhor abordagem ???

d-man
fonte

Respostas:

238

Vamos começar com um pouco de fundo: o que acontece quando você inicia um aplicativo?
O sistema operacional inicia um processo e atribui a ele um id de processo exclusivo e aloca uma tabela de processo. Um processo inicia uma instância de DVM (Dalvik VM); Cada aplicativo é executado dentro de um DVM.
Um DVM gerencia o descarregamento de carregamento de classe, ciclo de vida da instância, GC etc.

Vida útil de uma variável estática: Uma variável estática passa a existir quando uma classe é carregada pela JVM e morre quando a classe é descarregada.

Portanto, se você criar um aplicativo Android e inicializar uma variável estática, ela permanecerá na JVM até que um dos seguintes aconteça:
1. a classe é descarregada
2. a JVM é encerrada
3. o processo morre

Observe que o valor da variável estática persistirá quando você alternar para uma atividade diferente de outro aplicativo e nenhum dos três anteriores acontecer. Se qualquer um dos três acima acontecer, a estática perderá seu valor.

Você pode testar isso com algumas linhas de código:

  1. imprima a estática não inicializada em onCreate de sua atividade -> deve imprimir null
  2. inicialize o estático. imprima-o -> o valor não seria nulo
  3. Aperte o botão Voltar e vá para a tela inicial. Nota: a tela inicial é outra atividade.
  4. Inicie sua atividade novamente -> a variável estática não será nula
  5. Elimine o processo de aplicação do DDMS (botão de parada na janela de dispositivos).
  6. Reinicie sua atividade -> o estático terá valor nulo.

Espero que ajude.

Samuh
fonte
1
Eu quero saber por que eu perco o valor do meu campo no objeto do aplicativo se ele não é estático quando eu começo uma nova atividade, por exemplo, eu declaro a página atual da variável no objeto do aplicativo e seu valor sempre retorna a zero quando eu abro uma nova atividade
Mohammed Subhi Sheikh Quroush
quando eu chamo super.onRestoreInstanceState (savedInstanceState); Perco minhas variáveis ​​mesmo que sejam estáticas, qual é o problema?
Mohammed Subhi Sheikh Quroush
1
esta é uma boa explicação (então não -1), mas é um pouco inconseqüente: o OP perguntou explicitamente sobre "situações de pouca memória" (mesmo motivo pelo qual estou aqui), onde até onde eu sei o Os pode matar a VM e reinicie-o mais tarde com os mesmos parâmetros, e este caso ( SE for real) não é coberto aqui ...
Rick77
1
@suitianshi Acho que podemos inicializar instâncias estáticas em Application.onCreate, porque mesmo se nosso aplicativo entrar em segundo plano e o processo for interrompido, assim que voltarmos para nosso aplicativo, a classe Application será instanciada e chamará seus métodos de ciclo de vida correspondentes novamente! embora eu precise de confirmação sobre isso, gostaria de saber se poderia haver algum cenário em que a instância estática inicializada em Application.onCreate perde seu valor?
Sarthak Mittal
1
O que estou perdendo aqui é uma explicação para "1. a classe foi descarregada" - quando isso aconteceria? A JVM descarregaria uma classe se ela estivesse com pouca memória?
Stoefln
16

Bem, o padrão Singleton também se baseia no uso de variáveis ​​estáticas, então, na verdade, você estaria na mesma posição. Embora a abordagem estática possa funcionar na maioria das vezes, pode acontecer que, em alguns casos, quando a memória está cheia e outra atividade assume o primeiro plano antes que seu aplicativo passe para a próxima tela, o processo de sua atividade pode ser encerrado e você perder os valores estáticos. No entanto, o Android oferece algumas opções de persistir valores entre estados ou transmiti-los, como:

  • usando um Intent, você pode passar seus critérios de pesquisa de atividade em atividade (semelhante a uma solicitação http da web)
  • usando as preferências do aplicativo, você pode salvar os valores e recuperá-los na atividade que precisa deles
  • usando o banco de dados sqlite você pode persisti-los em uma tabela e recuperá-los mais tarde
  • se você precisar apenas salvar o estado da atividade para que, na reinicialização, os campos sejam preenchidos com seus valores previamente selecionados, você pode implementar o método de atividade onSaveInstanceState () - observe que isso não é recomendado para persistência de estados entre atividades.

Você pode obter alguns exemplos de código do uso de preferências, intenções e banco de dados sqlite olhando para a árvore de código-fonte aegis-shield no google code ou em outros aplicativos Android de código aberto.

r1k0
fonte
6

Depois de alguma pesquisa, descobriu-se que usar o aplicativo para armazenar singletons não é uma ideia tão boa, a menos que você esteja pronto para recriá-lo:

Não armazene dados no objeto do aplicativo

portanto, embora a resposta aceita seja tecnicamente correta, ela não fornece todas as informações.

Como o link acima sugere, se você realmente deseja manter esse modelo, você precisa estar pronto para verificar se há nulos e recriar os dados, se possível.

Rick77
fonte
3

@ r1k0 está bem aqui. O armazenamento de dados em campos estáticos de uma classe não persistirá por conta própria durante as eliminações e reinicializações do processo do aplicativo. O Android rotineiramente mata processos (aplicativos em execução) quando precisa de memória.

De acordo com o documento Android: estado de atividade e ejeção da memória ,

O sistema nunca mata uma atividade diretamente. Em vez disso, ele mata o processo no qual a atividade é executada, destruindo não apenas a atividade, mas também todo o resto em execução no processo.

Você pode salvar e restaurar o estado de primitivos, bem como de objetos serializáveis ​​e parceláveis, usando os métodos abaixo. Eles são chamados automaticamente durante o ciclo de vida normal da atividade.

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

Portanto, se você tiver uma classe que possui apenas variáveis ​​estáticas, pode salvar o estado de cada campo em onSaveInstanceState () e restaurá-los em onRestoreInstanceState (). Quando o Android interromper o processo em que seu aplicativo está sendo executado, o estado de suas variáveis ​​será salvo e, quando o Android restaurar seu aplicativo, os valores serão restaurados na memória no mesmo estado de antes.

eric.mcgregor
fonte