Consumindo Web Service no Android

Uma tarefa muito comum do dia a dia seria realizar requisições HTTP e consumir Web Services, mas as vezes pode ser um tanto quanto chata pois precisa de configurações e alguns passos a serem seguidos.

Para exemplo do post, vamos consumir um serviço para buscas de CEP, os passos que deveriamos seguir são:

  • Desenhar o layout
  • Consumir nosso serviço
  • Mostrar os dados consumidos para o usuário

Após concluir todos esses passos teremos nossa app funcionando da seguinte maneira:

Desenhando nossa app

O primeiro passo será criar o layout da nossa app, como o assunto do post refere-se ao web service, irei disponibilizar o layout:

Após adicionar esse layout para a activity, devemos ter nossa app parecido com:

Consumindo um serviço

Agora que o layout esta pronto, podemos começar a consumir nosso serviço, para isso alguns passos devem ser seguidos, sendo eles:

  • Adicionar um listener no botão Buscar CEP
  • Validar se o CEP foi digitado
  • Realizar a busca do CEP
  • Mostrar os dados para o usuário

Adicionando um listener no botão

Primeiro vamos começar adicionando um listener em nosso botão, para quando ele for clicado realizar alguma função, mas como podemos fazer isso ? Para trabalhar com eventos de click em botões podemos utilizar o setOnClickListener.

Vamos buscar nosso botão e atribuí-lo em uma variável:

Agora precisamos adicionar o listener no botão:

Pronto, com isso já devemos ser capazes de escutar e emitir alguma função quando o botão for clicado.

Criando a classe para buscar o CEP

Para realizar a busca do CEP vamos criar uma classe responsável por esse requisição HTTP:

Vou chamar a classe de HttpService pois a mesma irá consumir um serviço HTTP. Aqui entra um detalhe, toda requisição HTTP deve ser feita em background pelo Android, ou seja, a mesma não pode ser feita na thread principal, mas porque isso ocorre ?

Entendendo como uma requisição HTTP funciona

Uma requisição HTTP é feita da seguinte maneira:

  • Primeiro devemos configurar a requisição(URL, cabeçalhos e resposta)
  • Depois de configurada podemos realizar a requisição
  • Durante o processo de requisição devemos aguardar o servidor responsável processa-la
  • Após o servidor processa-la podemos pegar o retorno

Veja que no terceiro passo não sabemos quanto tempo o servidor irá levar para conseguir processar a requisição e devolver a resposta para a gente, por isso o Android exige que a requisição seja feita em background, assim o app não irá travar ou ficar congelado para o usuário enquanto a requisição é realizada.

Beleza Matheus, agora sabemos o motivo do Android exigir que a requisição seja feita em background ou em segundo plano, mas como podemos fazer isso ?

Adaptando nossa classe

O primeiro passo será extender a classe AsyncTask do Android responsável por realizar tarefas em background.

Opa, espera ae Matheus, que doidera é essa de Void, Void, CEP ?

Parâmetros do AsyncTask

Calma, vamos devagar, para tudo tem uma explicação, sempre que extendemos a AsyncTask devemos passar esse três parâmetros para ela, sendo eles:

  • Primeiro: Será o tipo de parâmetro enviado para a execução da classe
  • Segundo: Será o tipo de parâmetro recebido no método onProgressUpdate(não iremos utiliza-lo, o mesmo é chamado sempre que a requisição é atualizada, ideal para barras de progresso)
  • Terceiro: Será o tipo de retorno da classe

Criando o modelo CEP

Repare que o terceiro parâmetro da AsyncTask é uma classe CEP, mas ainda não temos ela, então vamos cria-la:

Veja que trata apenas de uma classe para representar e armazenar as informações de nosso CEP, não tem segredo.

Bom, agora que já extendemos a classe AsyncTask e conseguimos entender seus parâmetros, devemos sobrescrever o método responsável pela execução em background:

Realizando a requisição em background

O único método que somos obrigados a sobrescrever quando extendemos de AsyncTask é o doInBackground, como o próprio nome já diz, será o método responsável por realizar a requisição para nosso web service em background.

Para realizar a requisição precisamos de um CEP, mas em nossa classe não recebemos ele ainda, como podemos resolver o problema ? Se nossa classe HttpService precisa de um CEP para funcionar, porque não passar o CEP pelo construtor ? Assim garantimos que sempre ela terá um CEP ao ser instanciada(usada):

Veja que agora já possuímos um CEP para buscar os dados. O primeiro passo para nossa requisição funcionar será validar o CEP digitado e passado para nossa classe:

Repare que agora estamos validando se foi passado um CEP e se o mesmo contém oito dígitos.

Configurando e realizando a requisição

Vamos começar a configurar nossa requisição, o primeiro passo é termos uma URL para consumirmos:

Durante a construção da URL pode acontecer de passarmos uma inválida ou que não existe, por isso, devemos realizar um tratamento de exceção com try catch:

Agora precisamos abrir uma conexão e configurar os cabeçalhos dela(Tipo de requisição, tipo de retorno, tempo máximo de espera, etc…):

Com as configurações realizadas, precisamos de fato, realizar a conexão, ou seja, conectar em nossa url:

Pronto, ja conseguimos conectar, mas não basta conectar e realizar a requisição, precisamos de fato pegar a resposta e salvar em alguma variável, como podemos fazer isso ?

Lendo a resposta da requisição

Podemos ler a resposta facilmente com a classe Scanner do pacote java.io, ela abstrai bastante a complexidade de ler informações:

Beleza, estamos criando nosso scanner mas de onde ele vai ler as informações ? Para isso temos o método openStream em nossa url:

Como quase todas as classes do pacote java.io, devemos tratar a exceção para arquivos não encontrados, como já temos nosso try catch, precisamos apenas adicionar mais um catch em nosso try:

Agora, com as exceções tratadas e nosso scanner recebendo as informações, já podemos realizar a leitura da resposta:

Beleza, tudo certo ? Errado, até o momento lemos a resposta e passamos para a classe StringBuilder, porém, lembra que o terceiro parâmetro de nosso AsyncTask era do tipo CEP ? Pois é, sendo assim precisaremos retornar um CEP em nosso método doInBackground, pois até agora temos um JSON lido dentro de uma String:

Afinal, como podemos pegar esse JSON, gravar dentro de uma String e converte-lo para a classe CEP ?

Convertendo dados do json

Realizar a conversão de dados em Java pode ser algo trabalhoso, sabendo isso, a Google lançou uma biblioteca chamada GSON, responsável em abstrair a complexidade na hora de converter dados relacionados com JSON, para começar a usa-la, devemos declarar a dependência em nosso build.gradle:

Depois de adicionar a dependência, realize o sincronismo do Gradle.

Retornando um CEP

Com nosso GSON instalado, podemos converter nosso JSON para um objeto do tipo CEP da seguinte maneira:

Muito simples não ?

Agora que nossa classe responsável por realizar a requisição esta pronta, podemos utilizada em listener de nosso botão. Caso tenha se perdido em algum passo, segue a classe completa:

Retornando os dados para o usuário

Bom, até o momento de todos os passos que deveriamos realizar:

  • Adicionar um listener no botão Buscar CEP
  • Validar se o CEP foi digitado
  • Realizar a busca do CEP
  • Mostrar os dados para o usuário

Ja concluímos os três primeiros, portanto, precisamos apenas retornar os dados para o usuário.

Buscando os dados do CEP

Vamos começar buscando os dados do CEP digitado em nosso app, para isso já haviamos criado o listener, precisamos apenas fazer uso da nossa classe HttpService:

Com isso iremos ter o seguinte resultado:

Caso tenha ficado alguma dúvida, você pode encontrar o projeto completo aqui.


One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.