Exemplo Tutorial de Retrofit para Android

Bem-vindo ao Tutorial de Exemplo do Retrofit Android. Hoje vamos usar a biblioteca Retrofit desenvolvida pela Square para lidar com chamadas de API REST em nossa aplicação Android.

Retrofit Android

O Retrofit é um cliente REST tipo seguro para Android e Java que tem como objetivo facilitar o consumo de serviços web RESTful. Não iremos entrar em detalhes sobre as versões 1.x do Retrofit e iremos direto para o Retrofit 2, que possui muitos recursos novos e uma API interna alterada em comparação com as versões anteriores. O Retrofit 2 por padrão utiliza o OkHttp como camada de rede e é construído em cima dele. O Retrofit serializa automaticamente a resposta JSON usando um POJO (Plain Old Java Object) que deve ser definido antecipadamente para a Estrutura JSON. Para serializar JSON, precisamos de um conversor para convertê-lo em Gson primeiro. Precisamos adicionar as seguintes dependências em nosso arquivo build.grade.

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

A dependência do OkHttp já está incluída na dependência do Retrofit 2. Se desejar usar uma dependência separada do OkHttp, você deve excluir a dependência do OkHttp do Retrofit 2 como:

compile ('com.squareup.retrofit2:retrofit:2.1.0') {  
  // excluir o módulo de dependência do OkHttp do Retrofit e definir seu próprio módulo de importação
  exclude module: 'okhttp'
}
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.squareup.okhttp3:okhttps:3.4.1'
  • O interceptor de registro gera uma string de log de toda a resposta que é retornada.
  • Há outros conversores para analisar o JSON para o tipo necessário. Alguns deles estão listados abaixo.
  1. Jackson : com.squareup.retrofit2:converter-jackson:2.1.0
  2. Moshi : com.squareup.retrofit2:converter-moshi:2.1.0
  3. Protobuf : com.squareup.retrofit2:converter-protobuf:2.1.0
  4. Wire : com.squareup.retrofit2:converter-wire:2.1.0
  5. Simple XML : com.squareup.retrofit2:converter-simplexml:2.1.0

Adicione a permissão para acessar a internet no arquivo AndroidManifest.xml.

Interceptadores OkHttp

Os interceptadores são um mecanismo poderoso presente no OkHttp que pode monitorar, reescrever e tentar chamadas novamente. Os interceptadores podem ser divididos principalmente em duas categorias:

  • Interceptadores de Aplicação : Para registrar um interceptador de aplicação, precisamos chamar addInterceptor() em OkHttpClient.Builder
  • Interceptadores de Rede : Para registrar um Interceptador de Rede, invoque addNetworkInterceptor() em vez de addInterceptor()

Configurando a Interface Retrofit

package com.journaldev.retrofitintro;

import com.journaldev.retrofitintro.pojo.MultipleResource;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

class APIClient {

    private static Retrofit retrofit = null;

    static Retrofit getClient() {

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();


        retrofit = new Retrofit.Builder()
                .baseUrl("https://reqres.in")
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();



        return retrofit;
    }

}

O método getClient() no código acima será chamado sempre que configurarmos uma interface Retrofit. Retrofit fornece uma lista de anotações para cada um dos métodos HTTP: @GET, @POST, @PUT, @DELETE, @PATCH ou @HEAD. Vamos ver como nossa classe APIInterface.java se parece.

package com.journaldev.retrofitintro;

import com.journaldev.retrofitintro.pojo.MultipleResource;
import com.journaldev.retrofitintro.pojo.User;
import com.journaldev.retrofitintro.pojo.UserList;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;

interface APIInterface {

    @GET("/api/unknown")
    Call<MultipleResource> doGetListResources();

    @POST("/api/users")
    Call<User> createUser(@Body User user);

    @GET("/api/users?")
    Call<UserList> doGetUserList(@Query("page") String page);

    @FormUrlEncoded
    @POST("/api/users?")
    Call<UserList> doCreateUserWithField(@Field("name") String name, @Field("job") String job);
}

Na classe acima, definimos alguns métodos que realizam solicitações HTTP com anotação. @GET("/api/unknown") chama doGetListResources();. doGetListResources() é o nome do método. MultipleResource.java é uma classe de modelo POJO para nosso objeto de resposta que é usado para mapear os parâmetros de resposta para suas respectivas variáveis. Essas classes POJO atuam como o tipo de retorno do método. Uma classe POJO simples para MultipleResources.java é fornecida abaixo.

package com.journaldev.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;
import java.util.List;

public class MultipleResource {

    @SerializedName("page")
    public Integer page;
    @SerializedName("per_page")
    public Integer perPage;
    @SerializedName("total")
    public Integer total;
    @SerializedName("total_pages")
    public Integer totalPages;
    @SerializedName("data")
    public List<Datum> data = null;

    public class Datum {

        @SerializedName("id")
        public Integer id;
        @SerializedName("name")
        public String name;
        @SerializedName("year")
        public Integer year;
        @SerializedName("pantone_value")
        public String pantoneValue;

    }
}

A anotação @SerializedName é usada para especificar o nome do campo que está na Resposta JSON. Visualize a classe POJO e copie-a para a estrutura do projeto do seu Android Studio. As classes POJO são encapsuladas em uma classe Retrofit tipada Call. Nota: Um JSONArray é serializado como uma Lista de Objetos nas classes POJO Parâmetros do Método: Existem uma ampla variedade de opções possíveis de parâmetros para passar dentro de um método:

  • @Body – Envia objetos Java como corpo da solicitação.
  • @Url – usa URLs dinâmicas.
  • @Query – Podemos simplesmente adicionar um parâmetro de método com @Query e um nome de parâmetro de consulta, descrevendo o tipo. Para codificar uma consulta para URL, use o formato: @Query(value = "auth_token",encoded = true) String auth_token
  • @Field – envie dados como formulário codificado. Isso requer uma anotação @FormUrlEncoded anexada ao método. O parâmetro @Field funciona apenas com um POST

Nota: @Field requer um parâmetro obrigatório. Nos casos em que @Field é opcional, podemos usar @Query em vez disso e passar um valor nulo.

Estrutura do Projeto de Exemplo Retrofit Android

O pacote pojo define quatro classes de modelo para cada uma das respostas de ponto de extremidade da API definidas na classe APIInterface.java. User.java

package com.journaldev.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

public class User {

    @SerializedName("name")
    public String name;
    @SerializedName("job")
    public String job;
    @SerializedName("id")
    public String id;
    @SerializedName("createdAt")
    public String createdAt;

    public User(String name, String job) {
        this.name = name;
        this.job = job;
    }


}

A classe acima é usada para criar o Corpo da Resposta para o método createUser() UserList.java

package com.journaldev.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;
import java.util.List;

public class UserList {

    @SerializedName("page")
    public Integer page;
    @SerializedName("per_page")
    public Integer perPage;
    @SerializedName("total")
    public Integer total;
    @SerializedName("total_pages")
    public Integer totalPages;
    @SerializedName("data")
    public List<Datum> data = new ArrayList();

    public class Datum {

        @SerializedName("id")
        public Integer id;
        @SerializedName("first_name")
        public String first_name;
        @SerializedName("last_name")
        public String last_name;
        @SerializedName("avatar")
        public String avatar;

    }
}

CriarRespostaDoUtilizador.java

package com.journaldev.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

public class CreateUserResponse {

    @SerializedName("name")
    public String name;
    @SerializedName("job")
    public String job;
    @SerializedName("id")
    public String id;
    @SerializedName("createdAt")
    public String createdAt;
}

O MainActivity.java é onde chamamos cada um dos pontos de extremidade da API definidos na classe Interface e exibimos cada um dos campos em um Toast/TextView.

package com.journaldev.retrofitintro;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.journaldev.retrofitintro.pojo.CreateUserResponse;
import com.journaldev.retrofitintro.pojo.MultipleResource;
import com.journaldev.retrofitintro.pojo.User;
import com.journaldev.retrofitintro.pojo.UserList;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    TextView responseText;
    APIInterface apiInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        responseText = (TextView) findViewById(R.id.responseText);
        apiInterface = APIClient.getClient().create(APIInterface.class);


        /**
         GET List Resources
         **/
        Call<MultipleResource> call = apiInterface.doGetListResources();
        call.enqueue(new Callback<MultipleResource>() {
            @Override
            public void onResponse(Call<MultipleResource> call, Response<MultipleResource> response) {


                Log.d("TAG",response.code()+"");

                String displayResponse = "";

                MultipleResource resource = response.body();
                Integer text = resource.page;
                Integer total = resource.total;
                Integer totalPages = resource.totalPages;
                List<MultipleResource.Datum> datumList = resource.data;

                displayResponse += text + " Page\n" + total + " Total\n" + totalPages + " Total Pages\n";

                for (MultipleResource.Datum datum : datumList) {
                    displayResponse += datum.id + " " + datum.name + " " + datum.pantoneValue + " " + datum.year + "\n";
                }

                responseText.setText(displayResponse);

            }

            @Override
            public void onFailure(Call<MultipleResource> call, Throwable t) {
                call.cancel();
            }
        });

        /**
         Create new user
         **/
        User user = new User("morpheus", "leader");
        Call<User> call1 = apiInterface.createUser(user);
        call1.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                User user1 = response.body();

                Toast.makeText(getApplicationContext(), user1.name + " " + user1.job + " " + user1.id + " " + user1.createdAt, Toast.LENGTH_SHORT).show();

            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                call.cancel();
            }
        });

        /**
         GET List Users
         **/
        Call<UserList> call2 = apiInterface.doGetUserList("2");
        call2.enqueue(new Callback<UserList>() {
            @Override
            public void onResponse(Call<UserList> call, Response<UserList> response) {

                UserList userList = response.body();
                Integer text = userList.page;
                Integer total = userList.total;
                Integer totalPages = userList.totalPages;
                List<UserList.Datum> datumList = userList.data;
                Toast.makeText(getApplicationContext(), text + " page\n" + total + " total\n" + totalPages + " totalPages\n", Toast.LENGTH_SHORT).show();

                for (UserList.Datum datum : datumList) {
                    Toast.makeText(getApplicationContext(), "id : " + datum.id + " name: " + datum.first_name + " " + datum.last_name + " avatar: " + datum.avatar, Toast.LENGTH_SHORT).show();
                }


            }

            @Override
            public void onFailure(Call<UserList> call, Throwable t) {
                call.cancel();
            }
        });


        /**
         POST name and job Url encoded.
         **/
        Call<UserList> call3 = apiInterface.doCreateUserWithField("morpheus","leader");
        call3.enqueue(new Callback<UserList>() {
            @Override
            public void onResponse(Call<UserList> call, Response<UserList> response) {
                UserList userList = response.body();
                Integer text = userList.page;
                Integer total = userList.total;
                Integer totalPages = userList.totalPages;
                List<UserList.Datum> datumList = userList.data;
                Toast.makeText(getApplicationContext(), text + " page\n" + total + " total\n" + totalPages + " totalPages\n", Toast.LENGTH_SHORT).show();

                for (UserList.Datum datum : datumList) {
                    Toast.makeText(getApplicationContext(), "id : " + datum.id + " name: " + datum.first_name + " " + datum.last_name + " avatar: " + datum.avatar, Toast.LENGTH_SHORT).show();
                }

            }

            @Override
            public void onFailure(Call<UserList> call, Throwable t) {
                call.cancel();
            }
        });

    }
}

apiInterface = APIClient.getClient().create(APIInterface.class); é usado para instanciar o APICliente. Para mapear a classe Modelo para a resposta, usamos: MultipleResource resource = response.body(); Executar o aplicativo chamaria cada um dos pontos de extremidade e exibiria uma mensagem de Toast para eles conforme necessário. Isso encerra o tutorial de exemplo do Retrofit para Android. Você pode baixar o projeto de exemplo do Retrofit Android pelo link abaixo.

Baixe o Projeto de Exemplo do Retrofit para Android

Source:
https://www.digitalocean.com/community/tutorials/retrofit-android-example-tutorial