Android rxjava retrofit пример

Retrofit. Query, Path, RxJava, логи

Продолжаем говорить про Retrofit. Посмотрим, что и как мы можем настроить в нем, чтобы достичь своих целей.

Основы работы с Retrofit вы можете посмотреть в прошлом посте. Я же вкратце напомню, что две основных части его конфигурирования — это интерфейс и билдер. В интерфейсе мы описываем, какие методы мы будем вызывать, а в билдере задаем базовый URL и можем добавлять различные дополнения и обработчики для запросов и ответов.

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

Разделение ссылки

Предположим, у нас есть API метод:
http://server/api/v1/products/list.

Он возвращает список товаров. Нам нужно разделить эту ссылку на базовый URL (для билдера) и имя метода (для интерфейса). Это можно сделать так:
http://server/api/v1/products/ — базовый URL
list — метод

Соответственно, интерфейс будет выглядеть так:

Но внезапно у нас в API добавляется еще один метод, который возвращает список заказов:
http://server/api/v1/orders/list

Если его разделить по той же схеме, то получится так:
http://server/api/v1/orders/ — базовый URL
list — метод

В интерфейс мы можем добавить метод orderList:

Но у нас в билдере использовался базовый URL:
http://server/api/v1/products/

А нам теперь нужно, чтобы для метода ordersList он был таким:
http://server/api/v1/orders/

Можно конечно разделить все это на два отдельных интерфейса и билдера. Но есть решение и для текущей конфигурации. Надо просто по-другому выделять базовый URL из ссылок.

Берем две ссылки:
http://server/api/v1/products/list
http://server/api/v1/orders/list.

У них можно выделить общий базовый URL:
http://server/api/v1/

Его и будем использовать в билдере. А каталоги products и orders пойдут в интерфейс.

Query

Рассмотрим пример запроса с параметрами. Предположим, что метод http://server/api/v1/products/list поддерживает некоторые параметры.

Например, мы можем указать id категории товара:
http://server/api/v1/products/list?category=100

Или тип сортировки:
http://server/api/v1/products/list?sort=desc

Или оба вместе:
http://server/api/v1/products/list?category=100&sort=desc

В интерфейсе это можно сделать так:

И это даже будет работать, но понятно, что решение совсем топорное. Если сортировку еще можно так оставить, то категорию уж точно хотелось бы вынести в параметры. Используем для этого аннотацию Query:

Сортировку мы так и оставили там же, где указываем имя API метода. А категорию мы вынесли в параметры метода productList и добавили к ней аннотацию Query. В аннотации мы указали под каким именем этот параметр должен появится в URL запроса.

Вызов этого метода в коде будет выглядеть так:

И в результате будет выполнен следующий запрос
http://server/api/v1/products/list?sort=desc&category=100

В одном методе можно указывать несколько Query параметров.

Иногда API может быть такого вида

Т.е. здесь id товара передается не параметром, а частью пути. В этом случае нам поможет аннотация Path.

Используем ее в методах интерфейса:

В строку с именем метода добавляем плэйсхолдер в фигурных скобках. В параметры методов добавляем productId с аннотацией Path. В этой аннотации необходимо указать, в какой плэйсхолдер надо будет подставлять значение, пришедшее в productId. Указываем «id».

При вызове, Retrofit возьмет значение productId и подставит его в строку запроса вместо .

В одном методе можно указывать несколько Path параметров.

Логирование

Чтобы видеть, какие запросы уходят и какие ответы на них приходят, мы можем добавить к Retrofit логирование.

Читайте также:  Папка с миниатюрами андроид

Для этого надо в build.gradle в секцию dependecies добавить зависимость:

Код конфигурации билдера теперь будет выглядеть так:

Сначала создаем HttpLoggingInterceptor. В нем настраиваем уровень логирования. Если у нас Debug билд, то выставляем максимальный уровень (BODY), иначе — ничего не логируем, чтобы не палить в логах релизные запросы.

HttpLoggingInterceptor мы не можем напрямую передать в Retrofit билдер. Поэтому сначала создаем OkHttpClient, ему передаем HttpLoggingInterceptor, и уже этот OkHttpClient используем в Retrofit билдере.

В результате, в логе по тегу OkHttp вы увидите все ваши запросы со всеми параметрами, заголовками и содержимым.

RxJava

Чтобы использовать в проекте RxJava, необходимо добавить зависимости:

А для Retrofit нужен RxJava-адаптер:

Вместо обертки Call мы используем Single из RxJava. Он вернет нам либо результат (onNext), либо ошибку (onError). А метод завершения (onCompleted) он вызывать не будет.

В билдере нам необходимо добавить RxJava2CallAdapterFactory:

Далее, создаем реализацию MessageApi и вызываем метод messages.

Метод messages вернет нам Single
>, на который мы подписываемся и настраиваем, чтобы запрос был выполнен в IO потоке, а результат вернулся в UI потоке.,

В случае использования RxJava, у нас уже нет объекта Response. И если сервер вернет какую-то ошибку, то мы получим ее в onError. Например, ошибка 404 будет выглядеть так:

onError retrofit2.adapter.rxjava2.HttpException: HTTP 404

Как получить чистый текст

Бывает необходимость получить от сервера данные в виде текста (plain text). Т.е. вам не надо, чтобы Retrofit распарсил текстовые данные в объекты. По каким-то причинам вы хотите получить String.

В интерфейсе указываем тип String

Получить строку нам поможет конвертер ScalarsConverterFactory. Чтобы использовать его, пропишите зависимость:

Используем ScalarsConverterFactory в билдере

Далее, все как обычно, получаем Call объект и асинхронно выполняем запрос:

Ответ придет в response.body()

В логах это будет выглядеть так:

Мы получили нераспарсенные json данные в виде текста.

Как сделать синхронный вызов

Если вы собираетесь выполнять запрос не в UI потоке, то его можно выполнить синхронно без всяких колбэков.

Это будет выглядеть так:

Этот код блокирует текущий поток. Ответ от сервера вы получите в Response объект. А если случится ошибка, то она придет в catch

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Implementing RxJava2 & Retrofit2 for better performance during API calls

Jul 12, 2018 · 3 min read

API handling can be tedious if not completed in a good way. Loading data into an Android app can lag the UI thread if not done on a separate thread. RxJava2 and Retrofit2 are very powerful libraries that solve this problem. However, when you first get started with these libraries it can be very difficult to understand how to implement them in your application. I struggled with how to implement them and that is the sole reason I am writing this tutorial.

For this example w e are going to use an API that returns cryptocurrency data. You can click on this link to view the JSON it returns: https://min-api.cryptocompare.com/data/all/coinlist . However, here is the data we are interested in.

Читайте также:  Android или android hms

We will need two different POJO (Plain Old Java Object) classes. A great website that will provide you with the entire class laid out is JSONSchema, and all you need to do is paste the raw JSON in its editor.

The first POJO class will be CoinList.java for the entire response JSON. The second will be CryptoData.java which will be the data under the object Data inside the response.

Here is the CoinList.java POJO class.

Now for the CryptoData.java POJO Class.

Now add the dependencies for the libraries to your build.gradle . We are going to use RxJava2, Retrofit2, GSON, and a Retrofit2-RxJava2 Adapter.

Now that we have all the dependencies we can start implementing RxJava2 & Retrofit2. First off we will create our class that initializes Retrofit. We have to make sure we add the .addConverterFactory(GsonConverterFactory.create()) inside the getClient() method, this converts the response JSON into GSON and then into the POJO objects. We also need to make sure to add the .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) method, this verifies we are using RxJava2 for this API call.

Now we will call getClient() and utilize RxJava2 to run this on another thread and as you can see it is actually the AndroidSchedulers.mainThread() . This call will grab all the data at make objects out of it using the POJO classes and input it into the allCurrencyList variable List. Once this call is completed, inside the onComplete() method it calls another method that will update the UI. This is done by utilizing the MVP Architecture, therefore I was calling the Presenter to update the View from the Model.

Let me know what you think of this article down in the comments!

Give my Twitter a follow if you would like to keep up with my current projects. Do you invest in Cryptocurrencies? Check out my new app in Beta, Veox — Crypto currency portfolio tracker!

Источник

Fetch data using Retrofit and RxJava

Android multi-threaded REST requests

An example is available as a GitHub repository that linked at the end of the post.

We will see how to integrate Retrofit with RxJava to simplify threading in android app. This approach can be an alternative to AsyncTask which is deprecated by Google.

What is Retrofit?

A type-safe HTTP client for Android and Java. It makes it relatively easy to retrieve and upload JSON (or other structured data) via a REST based web-service. In Retrofit you configure which converter is used for the data serialization. Typically for JSON you use GSon, but you can add custom converters to process XML or other protocols. Retrofit uses the OkHttp library for HTTP requests.

To work with Retrofit we need the following three classes:

  • Model class which is used as a JSON model
  • Interfaces that define the possible HTTP operations ( GET, POST, etc..)
  • Retrofit.Builder class. Instance which uses the interface and the builder API to allow defining the URL end point for the HTTP operations.

What is RxJava?

RxJava is a Java VM implementation of ReactiveX, a library for composing asynchronous and event-based programs using observable sequences.
The building blocks of RxJava are observable and subscribers. Observable is used to emit items and the subscriber is used to consume those items. It is similar to the standard Observable model. But in fact, it’s much more flexible and fluid, making it a powerful programming paradigm.

We will display Covid progress statistics from a REST API.

Dependencies

First, import the dependencies of Retrofit and RxJava.

Читайте также:  Как восстановить контакты андроид через гугл

OkHttp interceptor may intercept the HTTP requests and responses, modify them. To see OkHttp responses logs you add personalized logging interceptor.

RxAndroid is an extension of RxJava for Android which is used only in Android application.

API modeling

Retrofit causing interfaces to return REST endpoint entities from JSON response.

Entity properties names must correspond to those JSON response. We can take a subset of properties. Retrofit doesn’t care about properties that are not in JSON or missing properties, it just defines what we need.

Instantiate retrofit service

Retrofit models REST endpoints as interfaces, making them very easy to understand and use.

Methods to build retrofit service :

  • BaseUrl set the API endpoint.
  • ConverterFactory responsible to convert Gson response to Serialized Java object.
  • CallAdapterFactory before talk about Call Adapter, you must know that retrofit execute HTTP request in background thread. Because It pushes the meaningless response bytes through converters and wraps it into a usable response with meaningful Java objects. Call Adapter is in charge to receives and prepares the result, to the Android UI thread.
  • Client add personalized HttpClient.

Create HTTP client with interceptors of requests and responses.

The request is intercepted and updated to add headers. But the request can be read only once, so the request must be rebuild( request.newBuilder() ) another time.

A HttpLoginInterceptor logs HTTP request and response data. You can redact headers that may contain sensitive information by calling redactHeader()

Make asynchronous calls to the API with RxJava

To call the API, it must be asynchronous and not with the UI thread. So RxJava allow us to do this. It makes the call in a worker thread and return the response in the UI thread.

RxJava allows to programming asynchronously thanks to observable flows. Data flow in RxJava is mainly made up of two elements:

  • An observable it represents the source of data transmission. an observable has sent its data as soon as one or more Subscribers begins to listen to it. An observable terminates its data transmission, either successfully or by returning an error.
  • A Subscriber (Observer) It represents the one who will listen to the Observable in order to recover its data transmission. To listen to the Observable, it simply subscribes to it.

You can imagine these two components by thinking of the course and the students participating in it: The courses (Data) are emitted by The teacher (Observable) and the students (Subscribers) subscribes for the courses to listen to them.

Remember that the result have Observable type. We need three methods of this object:

  • subscribeOn set the thread where data recovery will be performed.
  • observeOn set the thread where the Observer will listen to the Observable( the thread where the result will be returned).
  • subscribe set the Observer that will subscribe to the Observable in order to listen it.

I hope this has helped you. Good coding 😜 🤪

Источник

Оцените статью