[Из песочницы] Опыт применения Coroutines и Retrofit2

habr.png

Что это?

Кто еще не читал документацию — настоятельно рекомендую к ознакомлению.

Что пишет джетбрейнс:


Сопрограммы упрощают асинхронное программирование, оставив все осложнения внутри библиотек. Логика программы может быть выражена последовательно в сопрограммах, а базовая библиотека будет её реализовывать асинхронно для нас. Библиотека может обернуть соответствующие части кода пользователя в обратные вызовы (callbacks), подписывающиеся на соответствующие события, и диспетчировать исполнение на различные потоки (или даже на разные машины!). Код при этом останется столь же простой, как если бы исполнялся строго последовательно.

Если говорить простыми словами — это библиотека для синхронного \ асинхронного выполнения кода.


Зачем?

Потому что RxJava уже не в моде (шутка).

Во-первых, хотелось попробовать что-то новое, во-вторых, я наткнулся на статью — сравнение скорости работы корутин и других способов.


Пример

Например, нужно выполнить операцию в фоне.

Для начала — добавим в наш build.gradle зависимость от корутин:

Используем в нашем коде метод:

Где в context — мы указываем необходимый нам thread pool — в простых случаях это IO, Main и Default

IO — для простых операций с API, операциями с БД, shared preferencies и тд.
Main — UI тред, откуда мы можем получать доступ к вью
Default — для тяжелых операций с высокой нагрузкой на CPU
(Подробнее в этой статье)

Block — лямбда которую мы хотим выполнить

В принципе на этом все, мы получаем результат cуммы квадратов от 1 до 1000 и при этом не блокируем main thread что означает — никаких ANR

Однако, если наша корутина выполняется 20 секунд и за это время мы совершили 2 поворота девайса то мы будем иметь 3 одновременно выполняющихся block. Упс.

А если мы передали в block ссылку на activity — утечка и отсутствие возможности в старых блоках выполнить операции с view. Дважды упс.

Таки что делать?


Делаем лучше

Таким образом мы получили возможность останавливать выполнение нашего кода в потоке, например, при повороте экрана.

CoroutineScope сделал возможным объединить scope всех вложенных корутин и при вызове job.cancel () — останавливать их выполнение

При этом у нас остается возможность управлять потоками:


Подключаем retrofit2

Добавляем зависимости в градл:

Используем для примера ручку https://my-json-server.typicode.com/typicode/demo/posts

Описываем интерфейс ретрофита:

Опишем возвращаемую модель Post:

Наш BaseRepository:

Реализация PostsRepository:

Наш BaseUseCase:

Реализация GetPostsListUseCase:

Вот что получилось в итоге:


Делаем еще лучше

Я ленивое существо и не хочу каждый раз тянуть всю простыню кода, поэтому вынес нужные методы в BaseViewModel:

Теперь получения списка Posts выглядит так:


Вывод

Я использовал корутины в проде и код действительно получился чище и читабельнее.

© Habrahabr.ru