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.

terça-feira, 5 de abril de 2011

Loaders

Introduzido no Android 3.0, os loaders fazem ser mais fáceis o carregamento de dados de maneira assincrona nas atividades e fragmentos. Loaders tem as seguintes características:

  • Eles estão disponíveis em cada atividade e fragmento.
  • Eles provêem carregamento de dados de maneira assincrona.
  • Eles monitoram a fonte de seus dados e entregam novos resultados quando o conteúdo é modificado no back end.
  • Eles automaticamente reconectam para o último cursor do loader quando estão sendo recriados após uma mudança de configuração. Ou seja, eles não precisam fazer a chamada para recuperar os dados novamente (i.e. não é necessário passar novamente a query para o provider).
Sumário da API do Loader

Essas são as múltiplas classes e interfaces que estão involvidas no uso dos loaders em uma aplicação. Eles são listados nessa tabela:

Load manager
Uma classe abstrata associada com uma atividade ou fragmento para gerenciar uma ou mais intâncias de Loader. Isso ajuda uma aplicação no gerenciamento de operações que consomem tempo em conjunção com o ciclo de vida da atividade ou fragmento; o uso mais comum disso é o CursorLoader, contudo aplicações são livres para escrever seus proprios loaders para carregamento de outros tipos de dados.

Existe apenas um LoaderManager por atividade ou fragmento. Mas um LoaderManager pode ter múltiplos loaders.

LoaderManager.LoaderCallbacks
Uma interface de callback para um cliente para interagir com o LoaderManager. Por exemplo, você usa o método onCreateLoader() para criar um novo loader.

Loader
Uma classe abstrata que realiza o carregamento assincrono de dados. Ele é a classe base para o loader. Você tipicamente usará o CursorLoader mas você pode implementar sua própria subclasse. Enquanto os loaders estão ativos eles devem monitorar a fonte de seus dados e entregar novos resultados quando o conteúdo é mudado no back end.

AsyncTaskLoader
Loader abstrato que prove um AsyncTask para fazer o trabalho.

CursorLoader
Uma subclasse de AsyncTaskLoader que envia o query para o ContentResolver e retorna um Cursor. Essa classe implementa o protocolo Loader em uma forma padrão para fazer o envio de queries em cursores, contruindo o AsyncTaskLoader para realizar o query do cursor num thread de background para que ele não bloqueie a interface. Usando esse loader é a melhor maneira de capturar dados de maneira assincrona de um ContentProvider, ao invés de realizar um query gerenciado através do fragmento ou API da atividade.

As classes e interfaces acima listadas são componentes essenciais que você usará para implementar um loader para sua aplicação. Você não precisará de todos eles para cada loader que você criar mas você sempre necessitará de uma referência para o LoaderManager para inicializar o load e implementar uma classe Loader como CursorLoader.

Usando Loaders em sua aplicação

Uma aplicação que usa loaders tipicamente incluirá o seguinte:
  • Uma atividade ou fragmento
  • Uma instância do LoaderManager
  • Um CursorLoader para carregar dados guardados por um ContentProvider. Alternativamente, você pode implementar sua própria subclasse de Loader ou AsyncTaskLoader para carregar dados de outra fonte.
  • Uma implementação de LoaderManager.LoaderCallbacks. Isso é necessário para que seja criado novos loaders e gerenciar suas referências para loaders existentes.
  • Uma forma de mostrar os dados do loader, como um SimpleCursorAdapter.
  • Um data source, como um ContentProvider quando usando o CursorLoader.
Inicializando o Loader

O LoaderManager gerencia um ou mais instâncias de Loader dentro da atividade ou fragmento. Existe apenas um LoaderManager por atividade ou fragmento.

Você tipicamente inicializará o Loader dentro do onCreate() da atividade ou dentro do onActivityCreated() dentro do fragmento. Você faz isso da seguinte maneira:

// Prepare the loader.  Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);

O initLoader() recebe os seguintes parâmetros:
  • Um ID único que identifica o loader. No exemplo, o ID é 0.
  • Argumentos opcionais para suprir o loader na construção deste (null é um exemplo).
  • Uma implementação de LoaderManager.LoaderCallbacks à qual o LoaderManager chamará para reportar eventos de loader. No exemplo, a classe local implementa a interface LoaderManager.LoaderCallbacks e passa a referência de si mesmo, a palavra chave this.
O chamada ao initLoader assegura que o loader está inicializado e ativo. São duas as respostas a essa chamada:
  • Se o loader especificado já existe, o último loader criado será reutilizado.
  • Se o loader especificado não existe, o initLoader inicia o método onCreateLoader dentro de LoaderManager.LoaderCallbacks. Aqui é onde você implementa código para instanciar e retornar um novo loader.
Em ambos os casos, a implementação dada de LoaderManager.LoaderCallbacks é associada ao loader e será chamado quando o estado do loader for mudado. Se em algum ponto da chamada o método que faz a chamada está em estado inicializado e o loader requisitado já existe e tem dados, então o sistema chama onLoadFinished() imediatamente (duranto o initLoader()) portanto, esteja preparado para tal cenário.

Note que o método initLoader retornar o Loader que é criado mas não necessita capturar uma referência para ele. O LoaderManager gerencia a vida do loader automaticamente. O LoaderManager inicia e pára o carregamento quando necessário e mantém o estado do loader e de seus conteúdos associados. Como se pode supor, você raramente interagirá com os loaders diretamente. Você vai, mais comumente, usar os métodos dentro de LoaderManager.LoaderCallbacks para intervir em um processo de carregamento quando um evento particular ocorrer.

Reiniciando um Loader

Quando você usa o initLoader(), como mostrado acima, ele usa um loader existente com o ID especificado nele. Se não existe o ID, ele o cria. Mas algumas vezes você poderá querer descartar seus dados antigos e começar tudo de novo.

Para descartar seus dados antigos, use restartLoader(). Por exemplo, essa implementação de SearchView.OnQueryTextListener reinicia o loader quando a query do usuário é modificada. O loader precisa ser reiniciado para que possa ser usado para recriar os dados já que o filtro foi modificado.

public boolean onQueryTextChanged(String newText) {
    // Called when the action bar search text has changed.  Update
    // the search filter, and restart the loader to do a new query
    // with this filter.
    mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
    getLoaderManager().restartLoader(0, null, this);
    return true;
}

Usando os callbacks do LoaderManager

O LoaderManager.LoaderCallbacks é uma interface de callback que permite ao usuário interagir com o LoaderManager.

Loaders, em particular o CursorLoader, experam reter seus dados após serem parados. Isso permite à aplicação manter seus dados mesmo quando os métodos onStop() e onStart() são chamados na atividade ou fragmento, para que quando o usuário retorne à aplicação eles não tenham de esperar que os dados sejam novamente carregados. Você usa os métodos do LoaderManager.LoaderCallbacks quando precisa saber quando criar um novo loader e para dizer à aplicação quando é hora de parar de usar os dados do Loader.

O LoaderManager.LoaderCallbacks incluem os métodos:
  • OnCreateLoader() - Instancia e retorna um novo Loader para um dado ID.
  • OnLoadFinished() - Chamado quando um loader criado préviamente tem seu carregamento finalizado.
  • OnLoaderReset() - Chamado quando um loader criado préviamente está sendo resetado, fazendo com que seus dados fiquem indisponíveis.
 Existem exemplos diferentes em ApiDemos que ilustram como usar os loaders.

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...