Como recriar uma atividade

Estas são algumas possibilidades em que a atividade é destruída devido ao comportamento normal do aplicativo, como quando o usuário pressiona o botão Voltar ou sua atividade sinaliza a própria destruição chamando finish(). O sistema também poderá destruir a atividade se ela estiver interrompida e não tiver sido usada por um longo período de tempo ou se a atividade em primeiro plano exigir mais recursos. Assim, o sistema deverá fechar processos de segundo plano para recuperar memória.

Quando a atividade é destruída porque o usuário pressiona Voltar ou a atividade se encerra, o conceito do sistema daquela instância de Activity se perde porque o comportamento indica que a atividade já não é necessária. No entanto, se o sistema destruir a atividade devido a limitações do sistema (em vez de pelo comportamento normal do aplicativo), embora a instância real Activity tenha se perdido, o sistema lembrará que ela existiu de forma que, se o usuário navegar de volta, o sistema criará uma nova instância da atividade usando um conjunto de dados salvos que descrevem o estado da atividade quando ela foi destruída. Os dados salvos usados pelo sistema para restaurar o estado anterior são chamados de “estado da instância” e são uma coleção de pares de valor-chave armazenados no objeto Bundle.

Atenção: A atividade é destruída e recriada cada vez que o usuário gira a tela. Quando a tela muda de orientação, o sistema destrói e recria a atividade de primeiro plano porque a configuração da tela mudou e a atividade talvez precise carregar recursos alternativos (como o layout).

Por padrão, o sistema usa o estado da instância de Bundle para salvar informações sobre cada objeto View no layout da atividade (como o valor do texto informado em um objeto EditText). Assim, se a instância da atividade for destruída e recriada, o estado do layout será restaurado para o estado anterior sem que haja necessidade de código. No entanto, a atividade pode conter mais informações de estado do que se deseja restaurar, como variáveis de associação que rastreiam o progresso do usuário na atividade.

Observação: Para que o sistema Android restaure o estado das exibições na atividade, cada visualização precisa ter um ID exclusivo, fornecido pelo atributo android:id.

Para salvar dados adicionais sobre o estado da atividade, substitua o método de retorno de chamada onSaveInstanceState(). O sistema chama esse método quando o usuário sai da atividade e passa a ela o objeto Bundle, que será salvo caso a atividade seja destruída inesperadamente. Se o sistema precisar recriar a instância da atividade posteriormente, ele passará o mesmo objeto Bundle para ambos os métodos onRestoreInstanceState() e onCreate() .

Figura 2. Conforme o sistema começa a interromper a atividade, ele chama onSaveInstanceState() (1) para que você possa especificar outros dados de estado que gostaria de salvar se for necessário recriar a instância Activity. Se a atividade for destruída e for necessário recriar a mesma instância, o sistema passará os dados de estado definidos em (1) para os métodos onCreate() (2) e onRestoreInstanceState() (3).

Salvar o estado da atividade

Conforme a atividade é interrompida, o sistema chama onSaveInstanceState() para que a atividade possa salvar informações de estado com uma coleção de pares de valor-chave. A implementação padrão desse método salva informações sobre o estado da hierarquia de exibições da atividade, como o texto em um widget EditText ou a posição de rolagem de um ListView.

Para salvar informações de estado adicionais para a atividade, implemente onSaveInstanceState() e adicione pares de valor-chave ao objeto Bundle. Por exemplo:

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
    savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

Atenção: Sempre chame a implementação da superclasse de onSaveInstanceState() para que a implementação padrão salve o estado da hierarquia de exibições.

Restaurar o estado da atividade

Quando a atividade é recriada depois de ter sido destruída, é possível recuperar o estado salvo do Bundle que o sistema passou para a atividade. Os métodos de retorno de chamada onCreate() e onRestoreInstanceState() recebem o mesmo Bundle que contém informações do estado da instância.

Como o método onCreate() é chamado se o sistema estiver criando uma nova instância da atividade ou recriando uma anterior, verifique se o Bundle do estado é nulo antes de tentar realizar a leitura. Se for nulo, o sistema estará criando uma nova instância da atividade em vez de restaurar uma anterior que tenha sido destruída.

Por exemplo, esta é uma forma de restaurar alguns dados de estado no onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Restore value of members from saved state
        mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance
    }
    ...
}

Em vez de restaurar o estado durante onCreate(), é possível implementar onRestoreInstanceState(), que o sistema chama depois do método onStart(). O sistema chama onRestoreInstanceState() se houver um estado salvo a restaurar. Portanto, não é necessário verificar se Bundle é nulo:

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

Atenção: Sempre chame a implementação da superclasse de onRestoreInstanceState() para que a implementação padrão restaure o estado da hierarquia de exibições.

Para saber mais sobre recriação de atividades devido a um evento de reinicialização no tempo de execução (como quando a tela gira), consulte Processar alterações no tempo de execução.