Приложение "Погода". Retrofit 2 — работа с REST API в Android.

Урок 32 — Приложение "Погода". Retrofit 2 — работа с REST API в Android.

Давайте создадим наше последнее в этом курсе и самое грандиозное приложение — будем отображать погоду. Это же приложение мы выгрузим в Google Play в конце курса.

В первую очередь нам нужно какое-то бесплатное API для получения прогноза. Лучший на мой взгляд вариант — OpenWeatherMap. Зарегистрируйтесь на этом сервисе и получите ключ API.

OpenWeatherMap даёт 60 бесплатных запросов к API в минуту. Этого вполне достаточно для начала — если вы превысите количество запросов, то, я думаю, вы вполне сможете позволить себе платный тариф — он банально окупится рекламой.

Retrofit

Самый простой и распространённый, но при этом невероятно гибкий и мощный способ работы с API в Android — это библиотека Retrofit.

Добавим её в build.gradle:

implementation 'com.squareup.retrofit2:retrofit:2.3.0'

Retrofit, помимо прочего, работает не только с JSON, но и со многими другими форматами. Начиная с версии 2.0 парсинг различных форматов вынесен в отдельную сущность — конвертеры и каждый конвертер вынесен в отдельную библиотеку.

По этой причине нам будет нужно также подключить библиотеку для работы с JSON конвертером (в нашем случае — с использованием библиотеки GSON):

implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

Не забудьте добавить разрешение для доступа к интернету в манифест

Модели в Retrofit

В лучших традициях Android, API в Retrofit описывается декларативным образом — мы создаём декларативное описание моделей, которые будем получать из API, используя POJO — простые Java-объекты, и интерфейс, сообщающий, какие запросы мы будем отправлять.

Наверное, сейчас не очень понятно — давайте попробуем на практике.

Нас интересуют два запроса — текущая погода и прогноз на 5 дней. Начнём с первого:

https://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=ВАШ_КЛЮЧ_АПИ&units=metric

Что нас интересует в данном ответе?

  1. Поле main.
  2. Поле wind.
  3. Поле name.

Пока этого достаточно.

Создадим модели, начём с main:

public class ForecastMain {

    private float temp;

    private float pressure;

    private float humidity;

    @SerializedName("temp_min")
    private float minTemp;

    @SerializedName("temp_max")
    private float maxTemp;

    public float getTemp() {
        return temp;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    public float getMinTemp() {
        return minTemp;
    }

    public float getMaxTemp() {
        return maxTemp;
    }

}

Аннотация SerializedName позволяет указать имя поля в JSON, из которого будет десериализоваться поле в Java-объекте.

Теперь модель для поля wind:

public class ForecastWind {

    private float speed;

    @SerializedName("deg")
    private float degree;


    public float getSpeed() {
        return speed;
    }

    public float getDegree() {
        return degree;
    }

}

Теперь создадим объект, который будет отображать "корневую" структуру JSON-ответа и содержать нужные нам поля:

public class CurrentWeather {

    private ForecastMain main;

    private ForecastWind wind;

    @SerializedName("name")
    private String cityName;


    public ForecastMain getMain() {
        return main;
    }

    public ForecastWind getWind() {
        return wind;
    }

    public String getCityName() {
        return cityName;
    }
}

Интерфейс API

Теперь нужно создать интерфейс, который будет описывать API, к которому мы хотим получить доступ.

public interface Api {

    @GET("weather")
    Call<CurrentWeather> getCurrentWeather(
            @Query("lat") double latitude,
            @Query("lon") double longitude,

            @Query("appid") String apiKey,
            @Query("units") String units
    );

}

Пока что в нём лишь один метод, получающий текущую погоду. Давайте разберём его.

В первую очередь обратите внимание на аннотацию @GET. Она говорит о том, какой HTTP-метод будет использоваться — в нашем случае это, очевидно, GET. Возможные варианты:

  • GET
  • POST
  • PUT
  • PATCH
  • HEAD
  • DELETE
  • OPTIONS

В качестве единственного параметра передаётся путь до метода: мы используем URL https://api.openweathermap.org/data/2.5/weather, в этом случае путь — weather.

Параметры метода будут переданы в HTTP-запросе. В нашем случае это query-параметры, которые будут переданы прямо в URL.

Параметр аннотации @Query — название параметра для запроса.

Метод возвращает Generic-класс Call, который используется для выполнения запроса. Тип дженерика — это класс, объект которого мы хотим получить после выполнения запроса, то есть те десериализованные данные, которые придут нам в ответ на запрос.

Инстанциируем API

Последнее, что осталось сделать — создать объект, с помощью которого мы будем выполнять запросы к API.

Создадим для этого класс со статическим методом:

public class ApiFactory {

    public static Api createApi() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constants.API_BASE_URL) // Базовый URL
                .addConverterFactory(GsonConverterFactory.create()) // Конвертер JSON
                .build();

        return retrofit.create(Api.class);
    }

}

Константу API_BASE_URL я вынес в отдельный класс, туда же я вынес ключ API и дефолтную единицу измерения:


Продолжение доступно на платных тарифах

Это недорого — всего от 440 ₽ в месяц!


ВЫБРАТЬ ТАРИФ


Продолжение доступно после регистрации

Все уроки на сайте доступны абсолютно бесплатно после регистрации.

Регистрация займёт меньше минуты ;)