Caso prefira, você encontrará todo esse material, em inglês, no site do Developer Android. A tradução e comentários dos materiais eu faço livremente para ajudar a comunidade que fala português.

quarta-feira, 23 de março de 2011

Atividades - Gerenciando o ciclo de vida da atividade

Gerenciar o ciclo de vida de suas atividades implementando métodos callback é crucial para desenvolver uma aplicação forte e flexível. O ciclo de vida de uma atividade é diretamente afetada por suas associações com outras atividades, suas tarefas e seu back stack.

Uma atividade pode existir em três estados essencialmente:

Resumed
A atividade está sendo executada na tela e o usuário tem o foco. Esse estado também é referido como "rodando"

Paused
Outra atividade está sendo executada na tela e tem o foco, mas a atividade pausada ainda está visível. Ou seja, outra atividade está visível mas parcialmente transparente e não cobre a tela inteira. Uma atividade pausada está completamente viva (o objeto Activity continua na memória e seu estado é mantido juntamente com as informações e membros e mantêm-se anexada ao gerenciador de janelas) mas pode ser morto pelo sistema em situações de memória extremamente baixas.

Stopped
A atividade está completamente obscurescida por outra atividade (a atividade agora está em modo "background"). Uma atividade parada também está viva (o objeto Activity continua na memória e seu estado é mantido juntamente com as informações e membros e NÃO mantêm-se anexada ao gerenciador de janelas). Contudo, ela não está mais visível ao usuário e pode ser morta pelo sistema caso memória seja requerida em outro processo.

Mas tudo isso já foi coberto no post do Ciclo de Vida da aplicação.

Implementando os callbacks do ciclo de vida

Quando uma transação de atividade entre em um dos estados descritos acima, ele é notificado através de vários métodos de callback. Todos os callbacks podem ser sobrescritos para fazer o trabalho apropriado quando seu estado de atividade muda. O esqueleto de atividades abaixo inclui cada um dos métodos fundamentais do ciclo de vida:

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // A atividade está sendo criada
    }
    @Override
    protected void onStart() {
        super.onStart();
        // A atividade está para se tornar visível
    }
    @Override
    protected void onResume() {
        super.onResume();
        // A atividade se tornou visível (está em modo "resumed").
    }
    @Override
    protected void onPause() {
        super.onPause();
        // Outra atividade está ganhando o foco (está em modo "paused").
    }
    @Override
    protected void onStop() {
        super.onStop();
        //  A atividade não está mais visível (está "stopped")
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // A atividade está para ser destruída.
    }
}
Mais sobre os métodos em Ciclo de Vida da aplicação. Não deixe de ir lá pois há informações realmente válidas que ajudarão no entendimento desse tópico.

Salvando o estado da atividade


A introdução ao ciclo de vida da atividade rapidamente menciona que quando uma atividade está pausada ou parada, o estado da atividade é guardado. Isso é verdade pois o objeto de Activity é guardado na memória quando está pausado ou parado - todas as informações sobre seus membros e estado atual são mantidos vivos. Por isso, quaisquer alterações feitas pelo usuário dentro da atividade são mantidos em memória para que quando a atividade retorne para a tela (quando estiver em modo "resumed"), essas mudanças ainda estejam por lá.

Contudo, quando o sistema destroi uma atividade para recuperar memória, o objeto de Activity é destruído, então o sistema não pode simplesmente retornar ao estado anterior de maneira intacta. Ao invés disso, o sistema deve recriar o objeto se o usuário navegar de volta a ele. Ainda mais, o usuário não tem qualquer conhecimento de que o sistema destruiu a atividade e recriou-a e, na verdade, ele espera que a atividade esteja exatamente como estava anteriormente. Nessa situação, você pode assegurar que informações importantes sobre o estado de atividade estejam preservado implementando um método callback adicional que permite que você salve a informação sobre o estado da atividade e depois restaure-a quando o sistema precisar recriá-la.

O método callback que pode salvar informações sobre o estado atual de uma atividade é o onSaveInstanceState(). O sistema chama esse método antes de fazer com que a atividade esteja apta a ser destruída e passa esses dados para um objeto Bundle. O Bundle é onde você pode guardar informações de estado sobre a atividade como pares nome-valor, usando métodos como putString(). Então, se o sistema matar o processo de sua atividade e o usuário navegar de volta a ela, o sistema passa o Bundle para onCreate() para que quaisquer informações da atividade guardadas durante o uso de onSaveInstanceState() possam ser restauradas. Se não há nenhuma informação a ser restaurada, então o Bundle passado para o onCreate() é nulo (null).

Nota: Não há garantia que o onSaveInstanceState() seja chamado antes da atividade ser destruída, já que existem casos nos quais não será necessário salvar o estado (como quando um usuário deixa a atividade usando o botão de BACK em uma situação onde o usuário está explicitamente fechando a atividade). Se o método é chamado, ele deve ser chamado sempre antes de onStop() e possivelmente antes de onPause().

Contudo, mesmo quando você não faz nada ou não implementa o onSaveInstanceState(), algum dos estados de atividade são restaurados pela implementação padrão do onSaveInstanceState(). Especificamente há uma implementação padrão de onSaveInstanceState() para cada View do seu layout, que permite a cada View prover informações sobre si mesmo que devem ser salvas. Quase todo widget no framework Android implementa esse método como apropriado, tal como mudanças visíveis na interface que são automaticamente salvas e restauradas quando sua atividade é recriada. Por exemplo, o widget EditText salva qualquer texto que o usuário digitou dentro deste e o CheckBox salva a condição de estar ou não marcado. O único trabalho que você precisa ter é o de prover um ID único (com o atributo android:id) para cada widget que você quer ter o estado salvo. Se um widget não tem um ID, ele não terá seu estado salvo.

Apesar da implementação padrão de onSaveInstanceState() salvar dados úteis sobre a interface de uma atividade, você possivelmente ainda terá de sobrescrevê-lo para salvar informações adicionais. Por exemplo, você pode querer salvar valores que foram mudados durante o ciclo de vida da atividade.

Como a implementação padrão de onSaveInstanceState() ajuda a salvar o estado da interface, se você fizer a sobrescrita do método para salvar informações adicionais, você deve sempre chamar a implementação da supreclasse de onSaveInstanceState() antes de fazer qualquer trabalho adicional.

Nota: Como onSaveInstanceState() não é garantido de ser chamado, você deve usá-lo apenas para guardar o estado transiente da atividade - você NÃO deve usá-lo para guardar dados que precisam ser persistidos. Ao invés disso, você deve usar o onPause() para guardar dados que precisam ser persistidos (como dados que devem ser guardados em banco de dados).


Uma boa forma de testar a habilidade da aplicação para restaurar seu estado é simplesmente girar o seu dispositivo para que a orientação da tela mude. Quando a orientação muda, o sistema destrói e recria a atividade para que possa aplicar recursos alternativos que podem estar disponíveis na nova orientação. Por essa razão, é MUITO importante que sua atividade restaure completamente seu estado quando recriada, já que o usuário regularmente rotaciona a tela enquanto usa as aplicações.

0 comentários:

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Related Posts Plugin for WordPress, Blogger...