Ejemplo de Tutorial de Retrofit en Android

Bienvenido al Tutorial de Ejemplo de Retrofit Android. Hoy utilizaremos la biblioteca Retrofit desarrollada por Square para manejar llamadas a la API REST en nuestra aplicación Android.

Retrofit Android

Retrofit es un cliente REST seguro para Android y Java que tiene como objetivo facilitar el consumo de servicios web RESTful. No entraremos en los detalles de las versiones 1.x de Retrofit y pasaremos directamente a Retrofit 2, que tiene muchas características nuevas y una API interna cambiada en comparación con las versiones anteriores. Retrofit 2, de forma predeterminada, utiliza OkHttp como capa de red y se construye sobre ella. Retrofit serializa automáticamente la respuesta JSON utilizando un POJO (Plain Old Java Object) que debe definirse de antemano para la estructura JSON. Para serializar JSON necesitamos un convertidor para convertirlo primero en Gson. Necesitamos agregar las siguientes dependencias en nuestro archivo build.gradle.

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'

La dependencia OkHttp ya se incluye con la dependencia de Retrofit 2. Si desea utilizar una dependencia OkHttp separada, debe excluir la dependencia de OkHttp de Retrofit 2 de la siguiente manera:

compile ('com.squareup.retrofit2:retrofit:2.1.0') {  
  // Excluir el módulo de dependencia OkHttp de Retrofit y definir su propio módulo de importación
  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'
  • El interceptor de registro genera una cadena de registro de toda la respuesta que se devuelve.
  • Existen otros convertidores para analizar el JSON al tipo necesario. Algunos de ellos se enumeran a continuación.
  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

Agregue el permiso para acceder a internet en el archivo AndroidManifest.xml.

Interceptores de OkHttp

Los interceptores son un mecanismo potente presente en OkHttp que puede monitorear, reescribir y volver a intentar llamadas. Los interceptores pueden dividirse principalmente en dos categorías:

  • Interceptores de Aplicación: Para registrar un interceptor de aplicación, necesitamos llamar a addInterceptor() en OkHttpClient.Builder
  • Interceptores de Red: Para registrar un Interceptor de Red, invoque addNetworkInterceptor() en lugar de addInterceptor()

Configuración de la Interfaz de 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;
    }

}

El método getClient() en el código anterior se llamará cada vez al configurar una interfaz de Retrofit. Retrofit proporciona una lista de anotaciones para cada uno de los métodos HTTP: @GET, @POST, @PUT, @DELETE, @PATCH o @HEAD. Veamos cómo se ve nuestra clase APIInterface.java.

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);
}

En la clase anterior, hemos definido algunos métodos que realizan solicitudes HTTP con anotaciones. @GET("/api/unknown") llama a doGetListResources();. doGetListResources() es el nombre del método. MultipleResource.java es una clase de modelo POJO para nuestro objeto de respuesta que se utiliza para asignar los parámetros de respuesta a sus variables respectivas. Estas clases POJO actúan como el tipo de retorno del método. Una clase POJO simple para MultipleResources.java se muestra a continuación.

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;

    }
}

Se utiliza la anotación @SerializedName para especificar el nombre del campo que está en la respuesta JSON. Previsualiza la clase POJO y cópiala en la estructura de tu proyecto en Android Studio. Las clases POJO están envueltas en una clase Retrofit tipada Call. Nota: Un JSONArray se serializa como una Lista de Objetos en las clases POJO. Parámetros del Método: Hay una amplia variedad de opciones posibles de parámetros para pasar dentro de un método:

  • @Body – Envía objetos Java como cuerpo de la solicitud.
  • @Url – utiliza URLs dinámicas.
  • @Consulta – Simplemente podemos agregar un parámetro del método con @Consulta y un nombre de parámetro de consulta, describiendo el tipo. Para codificar una consulta en URL, use el formulario: @Consulta(valor = "auth_token", codificado = true) String auth_token
  • @Campo – enviar datos como form-urlencoded. Esto requiere una anotación @FormularioCodificadoUrl adjunta al método. El parámetro @Campo solo funciona con un POST

Nota: @Campo requiere un parámetro obligatorio. En casos en los que @Campo sea opcional, podemos usar @Consulta en su lugar y pasar un valor nulo.

Estructura del Proyecto de Ejemplo de Retrofit Android

El paquete pojo define cuatro clases de modelo para cada una de las respuestas de punto de API definidas en la clase 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;
    }


}

La clase anterior se utiliza para crear el cuerpo de respuesta para el 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;

    }
}

CreateUserResponse.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;
}

El MainActivity.java es donde llamamos a cada uno de los puntos finales de la API definidos en la clase Interface y mostramos cada uno de los campos en un 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); se utiliza para instanciar el APICliente. Para mapear la clase Modelo a la respuesta, usamos: MultipleResource resource = response.body(); Al ejecutar la aplicación, se llamaría a cada uno de los puntos finales y se mostraría un mensaje de Toast para ellos en consecuencia. Esto marca el final del tutorial de ejemplo de Retrofit para Android. Puedes descargar el proyecto de ejemplo de Android Retrofit desde el enlace debajo.

Descargar Proyecto de Ejemplo de Retrofit para Android

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