Страницы

Поиск по вопросам

среда, 12 декабря 2018 г.

Как правильно использовать Retrofit library?

Мне необходимо спроектировать Rest Api приложение. В интернете, в том числе в официальной документации показаны примеры использования данной библиотеки выполняя запросы напрямую из Activity, но это ведь неправильно?! Сетевые запросы нужно выполнять с помощью Service?! Как правильно это сделать c помощью Retrofit? Не хочу выдумывать свой "Велосипед".


Ответ

В официальной документации делается акцент на то, чтобы показать как использовать данную библиотеку, а не на то как лучше спроектировать приложение.
Я, например, использую связку retrofit+rxjava+eventbus и работаю по следующей схеме: методы ретрофита возвращают Observable вокруг которого я начинаю "накручивать" логику(запрос к серверу в отдельном потоке,обработчик ошибок, действия над результатом, обработчик успешного результата). В конце отправляю событие с флагом успешно ли прошел запрос или произошла какая либо ошибка. В итоге код выглядит следующим образом

public class RestInteractionWorker {
RestServerInterface restInterface;
public RestInteractionWorker(){ //создаем объект RestServerInterface }
public void perfomServerOperation(){ restInterface.perfomOperation(...) .subscribeOn(Schedulers.newThread()) //для запроса используем отдельный поток .timeout(30, TimeUnit.SECONDS) // таймаут .map(new Func1() { @NonNull @Override public ActionEvent call(T someModel) {
// обрабатываем результат, после чего высылаем событие с флагом успешного выполнения запроса return event; } }) .onErrorReturn(new Func1() { @NonNull @Override public ActionEvent call(Throwable throwable) { // произошла ошибка, создаем событие сообщающее об ошибке return new TownsTemperatureUpdateEvent(false); } }) .observeOn(AndroidSchedulers.mainThread()) // дальше код будет вызываться в главном потоке приложения .subscribe(new Action1() { @Override public void call(ActionEvent event) { EventBus.getDefault().post(event); // высылаем событие } }); } }
Интерфейс запросов к серверу выглядит так:

public interface RestServerInterface {
@GET("/...") Observable perfomOperation(...); }
Вместо T надо указать конкретный тип, который будет возвращен.
Данную модель я использую когда надо получить данные сервера и сохранить их в базу данных, после чего в приложении отобразить новые обновленные данные. В методе map(...) я сохраняю данные в бд, и возвращаю из него event с флагом успешной загрузки и сохранения данных, после чего в методе subscribe(...) высылаю это событие. В дальнейшем это событие перехватывает тот кто на него подписан и обновляет данные.
Метод onErrorReturn(...) перехватывает все исключения которые произошли во время выполнения.
Если не нужно сохранять данные в бд, а, например, сразу выслать модельный объект, то метод map(...) можно не реализовывать.
Классы событий выглядят примерно следующим образом:

public class ActionEvent {
private final boolean isSuccessefull; private final String message; //можно передавать дополнительную информацию
public ActionEvent(boolean isSuccessefull, String message) { this.isSuccessefull = isSuccessefull; this.message = message;
public boolean isSUccessefull() { return isSUccessefull; }
public String getMessage() { return message; } }
В активити/фрагменте обрабатываю события так:

public void onEvent(ActionEvent event) {
//обработка результата
}
public void onResume(){ EventBus.getDefault().register(this); // подписываемся на прием событий super.onResume(); }
public void onPause(){ EventBus.getDefault().unregister(this); // отписываемся от получения событий super.onPause(); }
Новичку данная модель может показаться сложноватой из-за использования библиотеки rxJava, но в целом для меня это довольно успешная модель реализации взаимодействия приложения с сервером.
Refrofit можно так же использовать в связке с Robospise. В ней как раз все запросы выполняются через Service. Пример можно найти в их репозиторие.

Комментариев нет:

Отправить комментарий