terça-feira, 19 de junho de 2018

Rumo ao Certificado Android: Ciclo de Vida de Uma Activity + InstanceState

Engraçado, acredito que é a primeira vez neste blog que eu retomo um assunto para complementar: neste post de 2011, quando eu ainda estava aprendendo a programar no Android (e os recursos da API eram bem mais limitadas), eu comentei sobre o ciclo de vida de uma Activity. Entretanto, era mais um básico para colocar o app funcionando do que entender o que realmente é o ciclo de vida da Activity.

Bem, o conceito original não mudou, mas agora temos bem mais detalhado:


No caso, para obter o certificado, é importante ter o ciclo de vida em mente. A imagem acima é um resumo dos casos mais comum, mas existem outros fatores que mexem no ciclo de vida da Activity. Por exemplo, mudando a orientação do telefone geralmente fará com que o aplicativo se adapte a nova orientação, e isso acaba fazendo com que o Activity seja destruído e reconstruído tendo como base a orientação.

O fato que se a Activity não está ativa e nem tem previsão de ficar, ela pode ser finalizada a qualquer momento, como podemos ver no ciclo de vida. Entretanto, se ainda existe a possibilidade dela retornar, existe um conceito que vai ajudar aqui: o Instance State.

Quando o sistema destrói uma activity sem que o mesmo fosse o desejo do usuário ou da programação, o sistema dá uma oportunidade de gerar um Instance State para salvar os dados necessários para recriar a atividade no mesmo ponto de quando a Activity foi posta para ser destruída. Isso é realizado principalmente pelos métodos: onSaveInstanceState onRestoreInstanceState.

O método onSaveInstanceState tem como parâmetro um objeto Bundle, que é onde vamos colocar os dados. Se não lembra, o Bundle é o mesmo objeto que vimos em Intents, só que ao invés de enviar as informações para outra Activity, nós vamos salvar nele as informações da própria Activity. O código abaixo mostra como podemos usar este método:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
    savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

    super.onSaveInstanceState(savedInstanceState);
}

Importante lembrar de sempre chamar o super e passar o Bundle para ele finalizar o processo.

Agora a activity já foi destruída e está sendo restaurada, vamos precisar fazer o reverso, e quem faz isso é o método onRestoreInstanceState. Ele vai receber como parâmetro a Bundle salva no método anterior, e com isso poderemos restaurar a tela. O código fica assim:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

Assim como o método anterior, é importante chamar o método do super para completar a restauração. Também vale a pena lembrar que o mesmo bundle pode ser obtido como parâmetro no método onCreate, podendo restaurar o mesmo lá, entretanto, para fins de restauração o ideal é utilizarmos o onRestoreInstanceState, que será chamado logo após a execução do onStart.

Para finalizar, é importante lembrar que o Instance State só estará disponível se a activity for destruída sem a intenção (na imagem, quando o fluxo vai para "App process killed"). Se o usuário desejou fechar o aplicativo ou o próprio aplicativo finalizou a activity (fluxo vai para "Activity shut down"), não será possível utilizar o Instance State.

Nenhum comentário:

Postar um comentário