Retrofit Esempio Tutorial Android

Benvenuti al Tutorial sull’Esempio di Retrofit Android. Oggi utilizzeremo la libreria Retrofit sviluppata da Square per gestire le chiamate API REST nella nostra applicazione Android.

Retrofit Android

Retrofit è un client REST type-safe per Android e Java che mira a rendere più facile consumare servizi web RESTful. Non entreremo nei dettagli delle versioni Retrofit 1.x e salteremo direttamente a Retrofit 2 che ha molte nuove funzionalità e un’API interna modificata rispetto alle versioni precedenti. Retrofit 2 utilizza per impostazione predefinita OkHttp come strato di rete e è costruito sopra di esso. Retrofit serializza automaticamente la risposta JSON utilizzando un POJO (Plain Old Java Object) che deve essere definito in anticipo per la struttura JSON. Per serializzare JSON abbiamo bisogno di un convertitore per convertirlo prima in Gson. Dobbiamo aggiungere le seguenti dipendenze nel nostro file 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'

La dipendenza OkHttp è già inclusa nella dipendenza Retrofit 2. Se desideri utilizzare una dipendenza OkHttp separata, dovresti escludere la dipendenza OkHttp da Retrofit 2 come segue:

compile ('com.squareup.retrofit2:retrofit:2.1.0') {  
  // escludi il modulo di dipendenza OkHttp di Retrofit e definisci il tuo modulo di importazione
  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'
  • Il logging-interceptor genera una stringa di log dell’intera risposta restituita.
  • Esistono altri convertitori per analizzare il JSON nel tipo necessario. Alcuni di essi sono elencati di seguito.
  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

Aggiungi il permesso per accedere a Internet nel file AndroidManifest.xml.

Interceptor di OkHttp

Gli interceptor sono un meccanismo potente presente in OkHttp che può monitorare, riscrivere e riprovare le chiamate. Gli interceptor possono essere suddivisi principalmente in due categorie:

  • Interceptor dell’applicazione : Per registrare un interceptor dell’applicazione, dobbiamo chiamare addInterceptor() su OkHttpClient.Builder
  • Interceptor di rete : Per registrare un interceptor di rete, invoca addNetworkInterceptor() invece di addInterceptor()

Configurazione dell’interfaccia 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;
    }

}

Il metodo getClient() nel codice sopra verrà chiamato ogni volta durante la configurazione di un’interfaccia Retrofit. Retrofit fornisce una lista di annotazioni per ciascun metodo HTTP: @GET, @POST, @PUT, @DELETE, @PATCH o @HEAD. Vediamo come appare la nostra classe 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);
}

Nella classe sopra, abbiamo definito alcuni metodi che eseguono richieste HTTP con annotazioni. @GET("/api/unknown") chiama doGetListResources();. doGetListResources() è il nome del metodo. MultipleResource.java è una classe Modello POJO per il nostro oggetto di risposta che viene utilizzato per mappare i parametri di risposta alle rispettive variabili. Queste classi POJO fungono da tipo di ritorno del metodo. Una semplice classe POJO per MultipleResources.java è fornita di seguito.

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;

    }
}

L’annotazione @SerializedName è utilizzata per specificare il nome del campo presente nella risposta JSON. Visualizza la classe POJO e copiala nella struttura del tuo progetto Android Studio. Le classi POJO sono incapsulate in una classe Retrofit tipizzata Call. Nota: Un JSONArray viene serializzato come una lista di oggetti nelle classi POJO Parametri del Metodo: Ci sono molte opzioni possibili di parametri da passare all’interno di un metodo:

  • @Body – Invia oggetti Java come corpo della richiesta.
  • @Url – utilizza URL dinamici.
  • @Query – Possiamo semplicemente aggiungere un parametro del metodo con @Query e un nome del parametro di query, descrivendone il tipo. Per codificare un URL di query, utilizzare il formato: @Query(value = "auth_token",encoded = true) String auth_token
  • @Field – invia dati come form-urlencoded. Questo richiede un’annotazione @FormUrlEncoded allegata al metodo. Il parametro @Field funziona solo con un POST

Nota: @Field richiede un parametro obbligatorio. Nei casi in cui @Field è facoltativo, possiamo utilizzare @Query invece e passare un valore nullo.

Struttura del Progetto di Esempio Retrofit Android

Il pacchetto pojo definisce quattro classi modello per ciascuna delle risposte degli endpoint API definite nella 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;
    }


}

La classe sopra viene utilizzata per creare il corpo della risposta per il metodo 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;
}

Il file MainActivity.java è dove chiamiamo ciascuno dei punti di accesso API definiti nella classe di interfaccia e mostriamo ciascun campo in 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); viene utilizzato per istanziare APIClient. Per mappare la classe Model alla risposta, usiamo: MultipleResource resource = response.body(); Eseguire l’applicazione chiamerà ciascuno dei punti di accesso e mostrerà un messaggio di Toast per ognuno di essi di conseguenza. Questo conclude il tutorial di esempio di Retrofit per Android. Puoi scaricare il progetto di esempio Android Retrofit dal link sottostante.

Scarica il progetto di esempio di Retrofit per Android

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