Пример установки Android Retrofit Руководство

Добро пожаловать в руководство по примеру Retrofit Android. Сегодня мы будем использовать библиотеку Retrofit, разработанную компанией Square, для обработки вызовов REST API в нашем приложении Android.

Retrofit Android

Retrofit – это типобезопасный REST-клиент для Android и Java, который призван упростить потребление служб веб-сервисов RESTful. Мы не будем вдаваться в детали версий Retrofit 1.x и перейдем непосредственно к Retrofit 2, который имеет много новых функций и измененный внутренний API по сравнению с предыдущими версиями. Retrofit 2 по умолчанию использует OkHttp в качестве сетевого слоя и построен на его основе. Retrofit автоматически сериализует JSON-ответ с использованием POJO (Plain Old Java Object), который должен быть предварительно определен для структуры JSON. Для сериализации JSON нам нужен конвертер для преобразования его сначала в Gson. Мы должны добавить следующие зависимости в наш файл 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'

Зависимость OkHttp уже включена в зависимость Retrofit 2. Если вы хотите использовать отдельную зависимость OkHttp, вы должны исключить зависимость OkHttp из Retrofit 2, как показано ниже:

compile ('com.squareup.retrofit2:retrofit:2.1.0') {  
  // исключить модуль зависимости OkHttp Retrofit и определить собственный модуль импорта
  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'
  • Логгирование-интерсептор генерирует строку журнала для всего ответа, который возвращается.
  • Существуют и другие конвертеры для разбора JSON в необходимый тип. Некоторые из них перечислены ниже.
  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

Добавьте разрешение на доступ к интернету в файле AndroidManifest.xml.

OkHttp Перехватчики

Перехватчики – мощный механизм в OkHttp, который может отслеживать, переписывать и повторять вызовы. Перехватчики можно разделить на две основные категории:

  • Перехватчики приложения : Чтобы зарегистрировать перехватчик приложения, нам нужно вызвать addInterceptor() на OkHttpClient.Builder
  • Сетевые перехватчики : Чтобы зарегистрировать сетевой перехватчик, используйте addNetworkInterceptor() вместо addInterceptor()

Настройка интерфейса 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;
    }

}

Метод getClient() в вышеуказанном коде будет вызываться каждый раз при настройке интерфейса Retrofit. Retrofit предоставляет список аннотаций для каждого из методов HTTP: @GET, @POST, @PUT, @DELETE, @PATCH или @HEAD. Давайте посмотрим, как выглядит наш класс 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);
}

В этом классе мы определили несколько методов, выполняющих HTTP-запросы с использованием аннотаций. @GET("/api/unknown") вызывает doGetListResources();. doGetListResources() – это имя метода. MultipleResource.java – это модельный класс POJO для нашего объекта ответа, который используется для сопоставления параметров ответа и их соответствующих переменных. Эти классы POJO действуют как тип возвращаемого метода. Простой класс POJO для MultipleResources.java приведен ниже.

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;

    }
}

@SerializedName используется для указания имени поля в JSON-ответе. Просмотрите класс POJO и скопируйте его в структуру проекта Android Studio. Классы POJO обернуты в типизированный класс Retrofit Call. Примечание: JSONArray сериализуется как список объектов в классах POJO. Параметры метода: Существует множество возможных вариантов параметров для передачи внутри метода:

  • @Body – Отправляет объекты Java в теле запроса.
  • @Url – Используйте динамические URL.
  • @Query – Мы можем просто добавить параметр метода с @Query и именем параметра запроса, описывающим тип. Для кодирования запроса в URL используйте форму: @Query(value = "auth_token", encoded = true) String auth_token
  • @Field – отправка данных в формате form-urlencoded. Для этого требуется аннотация @FormUrlEncoded, присоединенная к методу. Параметр @Field работает только с методом POST

Примечание: @Field требует обязательного параметра. В случаях, когда @Field является необязательным, мы можем использовать @Query вместо этого и передавать значение null.

Структура Примера проекта Retrofit Android

В пакете pojo определены четыре модельных класса для каждого из ответов на конечные точки API, определенные в классе 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;
    }


}

Вышеупомянутый класс используется для создания тела ответа для метода 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;
}

В MainActivity.java мы вызываем каждый из определенных в классе Interface конечных точек API и отображаем каждое из полей в 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); используется для создания экземпляра APIClient. Для сопоставления класса Model с ответом мы используем: MultipleResource resource = response.body(); Запуск приложения вызовет каждую из конечных точек и отобразит для них сообщение Toast соответственно. Это завершает пример учебника по Retrofit для Android. Вы можете скачать проект примера Android Retrofit по ссылке ниже.

Скачать проект примера Retrofit для Android

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