Upload
fernando-camargo
View
894
Download
0
Embed Size (px)
Citation preview
Android – Carregando dados com Loaders
●Motivação:➔Organização das Threads no Android➔UI Thread e operações longas➔Operações longas em outras threads●Vida sem os Loaders●Introdução aos Loaders●Prática
Apresentação
Fernando Camargo:
● Graduando do curso de Engenharia de Computação na UFG
● Estuda Java desde 2009 e Android desde o início de 2012
● OCJP 6
● Desenvolve para Java EE, Android e Grails
● Fazendo estágio na Fibonacci Soluções Ágeis
Motivação
● Como são organizadas as threads no Android?
● Qual thread é responsável pela criação da interface com o usuário?
● Qual é a diferença dela para threads comuns?
● Outras threads podem modificar a interface com o usuário?
● O que acontece quando a thread responsável por tal interface fica muito tempo em uma operação longa?
● Como rodar operações longas e modificar a interface com o usuário de forma segura?
Organização das Threads
A organização das threads no sistema Android é bem simples:
● UI Thread
Thread principal e única responsável por construção e atualização da tela. Todo o ciclo de vida de uma Activity roda nessa thread. Nenhuma outra thread pode modificar a tela.
● Demais threads
Geralmente lançadas para executar tarefas em paralelo. Não pode fazer qualquer modificação na tela.
UI Thread e operações longas
Toda e qualquer operação longa (interações com o banco de dados e a internet, por exemplo) deve ser evitada na UI Thread, pois pode causar travamento e ANRs (Application Not Responding).
Operações longas em outras threads
Todas as operações longas devem ser feitas em outras threads. Porém, tais threads não podem alterar a tela. Então como podemos atualizá-la ao fim da operação?
● Handler
● runOnUiThread(Runnable)
● AsyncTask
● Loaders
Handler
Cria-se uma nova thread para executar a operação longa. Ao fim da mesma, usa-se o handler para se comunicar com a UI Thread, para que essa faça as atualizações na tela.
Devido à sua complexidade, não é amplamente usado.
runOnUiThread(Runnable)
Método de Activity que pode ser chamado por outra thread. Passa-se um Runnable que será executado na UI Thread.
AsyncTask
Uma forma mais simples de executar tarefas em segundo plano e fazer atualizações na tela. Seu uso substitui o uso dos complicados Handlers.
Trata-se de uma classe abstrata com os seguintes métodos a serem implementados:
● onPreExecute: Executado na UI Thread antes da execução da tarefa.
● doInBackground: Executado em segundo plano por outra thread.
● onPostExecute: Executado após a execução da tarefa na UI Thread. Geralmente usado para atualizar a tela.
AsyncTask (2)
O desenvolvedor deve estender essa classe implementando pelo menos o método doInBackground. Com uma instância dessa subclasse, deve-se chamar o método run. Também é possível cancelar a tarefa usando o método cancel.
Vida sem os Loaders
Essas dumas formas de executar operações longas em outra thread e atualizar a tela (em especial AsyncTask), são ótimas. Mas e quando precisamos especificamente carregar e monitorar uma fonte de dados que alimentará nossa aplicação?
Com AsyncTask, teríamos uma tarefa responsável por carregar os dados e outra para monitorar as modificações no mesmo, sendo que essa deveria ser reinicializada após seu término.
Implementar isso pode ser complicado e possuir erros.
Introdução aos Loaders
Foram introduzidos no Android 3.0 e portados através de uma biblioteca de compatibilidade para versões anteriores. Tornam fácil o carregamento de dados em Activity's e Fragment's (esse não será apresentado aqui).
● Fornecem carregamento assíncrono de dados.
● Monitoram a fonte de dados e entregam novos resultados quando o conteúdo muda.
● Reconectam automaticamente quando há uma mudança de configurações (quando o usuário vira o smartphone, por exemplo).
LoaderManager
Gerenciador dos Loaders de uma determinada Activity ou Fragment. Ajuda a aplicação a gerenciar operações longas em conjunção com o ciclo de vida de seu(sua) respectivo(a) Activity ou Fragment.
Com a biblioteca de compatibilidade, pode ser obtido através do método getSupportLoaderManager(), presente na classe FragmentActivity.
Os Loaders são iniciados através de seu método initLoader e reiniciados através de seu método restartLoader. Um Loader também pode ser recuperado através do método getLoader.
LoaderCallbacks
Uma interface a ser implementada e passada para o LoaderManager no momento da (re)inicialização de um Loader. Os métodos dessa interface rodaram na UI Thread.
● onCreateLoader: Método responsável por retornar uma instância de Loader a ser usado pelo LoaderManager.
● onLoadFinished: Método chamado após a chegada de novos resultados. Geralmente usado para atualizar a tela com os novos dados.
● onLoaderReset: Método onde se deve limpar os dados previamente carregados pelo Loader, pois tais dados ficarão indisponíveis.
Loader
Classe abstrata que realiza carregamento assíncrono de dados. Enquanto ativos, também devem monitorar a fonte de dados e entregar novos resultados quando o conteúdo mudar.
Geralmente, deve-se criar uma subclasse da classe AsyncTaskLoader (classe que utiliza AsyncTask para realizar o carregamento e monitoramento em outra thread). Uma subclasse de AsyncTaskLoader pode sobrescrever os métodos: loadInBackground, deliverResult, onStartLoading, onStopLoading, onCanceled, onReset, entre outros.
CursorLoader
Já existe implementada a classe CursorLoader, subclasse de AsyncTaskLoader. Através dela, pode-se usar Loaders com Cursor de um banco de dados sem se preocupar em criar uma subclasse de Loader. O monitoramento de dados é feito através de um Observer que observa notificações do Content Provider.
Prática
Aplicativo de leitura de contatos cadastrados no Aplicativo apresentado anteriormente. Esse aplicativo será bem simples e fará o seguinte:
● Apresentará uma tela de login para o usuário logar em sua conta.
● Se comunicará com um webservice para fazer autenticação.
● Possuirá um Loader que se comunicará com um webservice para carregar os contatos.