Desenvolvendo para Android – Como descarregar dados da cloud utilizando uma AsyncTask

Standard

Depois do ultimo post em que vimos mecanismos para carregar os dados  de uma fonte como um array e fazer com que sejam disponibilizados em uma ListView, vamos continuar a Série e aprender como fazer coisas mais interessantes e nos tornarmos em Desenvolvedores Android Ninjas. Várias vezes queremos fazer aplicações para mostrar horários dos filmes de um cinema, mostrar os últimos tweets de uma certa tag, mostrar os vídeos de um canal do youtube ou mostar os posts de uma determinada conta do Tumblr mas não sabemos necessariamente por onde começar e fazer com que a nossa idea ganhe vida.

Para que possamos superar estes inconvenientes, neste post irão aprender como:

  • O que é uma API?
  • Exemplos de API’s Interessantes.
  • Conectar a uma API utilizando o protocolo HTTP.
  • Realizar a operação de conexão a API dentro de uma AsyncTask
  • O que é o JSON.
  • Processar a resposta do API disponibilizado em formato de um JSON.
  • Mostrar os dados em uma ListView.

O que é uma API?

Uma  “Application Programing Interface”  ou normalmente conhecida pelo seu acrónimo API, é um conjunto de padrões ou instruções de programação para o acesso a uma aplicação   ou as suas funcionalidades sem que haja a necessidade saber como a aplicação ou funcionalidade foi desenvolvida. Várias empresas como Google, Facebook, Twitter etc, desenvolvem API’s para que os programadores possam criar e implementar aplicações terceiras que usufruam dos serviços oferecidas por eles. Uma das API’s mais comuns de ver tanto em websites como em apps, é a API dos Maps disponibilizada pela Google que permite que o Web Developer possa colocar um mapa no seu website utilizando apenas um código disponibilizado ou que mobile App Developers possam utilizar serviços de localização em suas aplicações. Abaixo estão listadas algumas API’s muito utilizadas no mundo:

Para dar continuidade ao post,  iremos de seguida escrever o código para conectar ao servidor do OpenWeather API, buscar os dados de temperatura para uma determinada cidade e de seguida processar a resposta e disponibilizar na lista do projecto criado no post anterior.

Para começar vamos abrir a classe FragmentLista e adicionar o método disponível no gist aqui. O método adicionado será responsável por fazer uma conexão pelo protocolo http a url que ele recebe como parâmetro e ira devolver uma string como resposta que nos esperamos que seja a resposta no formato JSON do pedido que tenhamos feito a url. Explicando um bocadinho o que acontece neste método,o processo e o seguinte :

  • Primeiro criamos uma url apartir da string que o método recebe como parâmetro utilizando a classe URL.
  • De seguida Criamos e inicializamos uma conexão a url criada no passo anterior. Para inicializar a conexão podemos utilizar a classe HTTPUrlConnection ou outras bibliotecas como OKHTTP(Oferecem melhor performance).
  • Por fim fazemos a leitura dos bytes do fluxo de entrada (InputStream) e vamos construindo uma String utilizando a classe BufferedReader e fazer com o método a retorne.

Ate então, se por algum motivo decidíssemos invocar o método neste momento, poderíamos nos deparar com o erro  android.os.NetworkOnMainThreadException  que é causado por estarmos a fazer uma operação de connectar a rede que não sabemos em que momento poderá terminar dentro da thread princiapl Main.

Este erro acontece porque de acordo com as especificações disponíveis aqui, a Main thread é responsável por despachar eventos para um determinado widget da interface gráfica e interagir com o Android UI toolkit (componentes do pacote android widget e  android.view).

Pelas razões citadas a pouco, realizar tarefas que não sabemos em que momento terminariam dentro da main thread vai fazer com que a nossa aplicação não consiga reagir aos eventos activados pelo utilizador e posteriormente causar com que a aplicação pare de Executar.

Dentro de uma AsyncTask somos obrigados a implementar um método de nome doInBackground mas maioria das vezes podemos querer implementar pelo menos os 3 métodos abaixo:

  • onPreExecute(): O método onPreExecute é executado antes de iniciar a nova thread no background para realizar o trabalho que nos pretendemos . Este método é executado na UI Thread.
  • doInBackground(Params… param): o método do In background é onde realizamos todas as nossas operacoes que não sabemos quanto tempo podem levar (descarregar uma imagem, connectar a uma API). Este método recebe um parâmetro  do mesmo tipo que passamos ao extender a classe e retorna também o tipo de dados definido ao extender a classe. Este método e executado fora da UI Thread.

onPostExecute(Param param): O método on post execute é invocado de volta na UI Thread e recebe como parâmetros os dados retornados pelo método doInBackground. É neste método que podemos começar a definir os dados nos componentes após o fim do método doInBackground.

No nosso caso, ao executar o pedido o servidor responde-nos com uma String em formato JSON. Mas afinal de contas o que é o JSON?

JSON significa JavaScript Object Notation, e  é um formato muito utilizado para troca de dados. O JSON tem várias vantagens como permitir  a facil leitura e escrita pelos seres humanos assim como pelos computadores.

Basicamente o JSON representa os dados em forma de chave-valor e podem ser representados tipos de dados primitivos, objectos e arrays. Para mais informações sobre o JSON a W3Schools tem um tutorial muito bom AQUI

Para descodificar a resposta do nosso servidor que está no formato JSON, vamos utilizar duas classes bastantes úteis para o efeito que são JSONObject e JSONArray. A implementação completa do AsyncTask como uma classe interna do Fragment que temos a lista encontra-se AQUI.

Com a AsyncTask criada, só nos resta modificar o código dentro do onCreate() do fragment em que fazemos o set do adapter com o array que tinhamos pre-definido, para utilizar a asynctask como esta aqui.

Conclusão

Com este post foi possível aprender o básico de como fazer conexao a uma url utilizando o protocolo HTTP e como fazer de forma correcta para  que esta tarefa seja executada em uma thread que nao afecta a responsividade da nossa aplicação. Gostaria de terminar o post dizendo que a idea do fundo deste post em particular era deixar a conhecer a classe AsyncTask como forma de realizar operacoes(descodificar bitmaps, descarregar dados da rede etc.) em uma thread separada . Para o nosso exemplo em que estávamos a fazer uma conexão a uma API, existem bibliotecas como OkHTTP e Volley que permitem fazer o mesmo de forma muito mais eficiente.

Como sempre, espero pelos feedbacks, questões etc.

Ate mais =)

DM!

Advertisements

12 thoughts on “Desenvolvendo para Android – Como descarregar dados da cloud utilizando uma AsyncTask

  1. Silvestre

    parabens pelos posts compreensiveis.
    A minha questao e: tem um site k disponibiliza o json da hora actual de mocambique? No caso afirmativo peco-o

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s