Android kotlin coroutines gradle

Применяем Kotlin Coroutines в боевом Android-проекте

Coroutines Kotlin VS RxJava в асинхронном коде

Думаю, для тех, кто не знаком с Kotlin , стоит сказать пару слов о нем и корутинах в частности. Об актуальности изучения Kotlin говорит то, что в мае 2017 года компания Google сделала его официальным языком разработки Android.

Проекты, стартующие в нашей компании, мы пишем на Kotlin, поэтому изучаем существующие возможности и следим за выходом новых. Когда создатели языка анонсировали корутины как новый инструмент асинхронного программирования, стало интересно протестировать их в боевых условиях. Судя по описанию возможностей, они как раз подходят для решения наших задач и отличаются в лучшую сторону от уже существующих решений.

Итак, для чего нужны корутины ? Если требуется скачать что-то из сети, извлечь данные из базы данных или просто выполнить долгие вычисления и при этом не заблокировать интерфейс пользователю, можно использовать корутины.

В контексте Android в задачах обеспечения асинхронности их смело можно рассматривать как конкурента RxJava . Несмотря на то, что возможности RxJava гораздо шире (это довольно объемная библиотека со своим подходом и философией), работать с корутинами удобнее, потому что они — всего лишь часть языка программирования. Задачи, решенные на RxJava с помощью операторов (специальных методов библиотеки), на корутинах реализуются намного проще — через встроенные средства языка. К тому же операторы библиотек нужно не только знать, но и понимать, как они работают, правильно выбирать и применять. Конечно, средства языка знать и правильно применять тоже нужно, но, когда речь идет о сокращении времени на разработку, стоит задуматься, насколько изучение возможности библиотеки, которую используешь для решения небольшой задачи, актуально в сравнении с изучением языка, на котором пишется весь проект.

Примеры использования Coroutines Kotlin

Поддержка корутин встроена в Kotlin, но все классы и интерфейсы находятся в отдельной библиотеке. Для их использования нужно добавить зависимость в gradle:

Небольшой пример использования:

Разберемся, что тут происходит.

longRunningMethod() — метод, который нам нужно выполнить асинхронно.

GlobalScope — жизненные рамки для корутины. В данном случае корутина будет жить, пока живо приложение, в котором она запущена. GlobalScope — конкретная реализация интерфейса CoroutineScope. Можно реализовать свой scope, например, в Activity, и это приведет к тому, что запущенные в Activity корутины будут автоматически отменяться в случае завершения или краша Activity.

launch — метод для асинхронного запуска корутины. Соответственно, метод longRunningMethod() запустится сразу же. Метод возвращает экземпляр класса Job. Этот объект можно использовать для того, чтобы, например, отменить корутину — job.cancel(). Альтернатива — метод asunc(). Он вернет Deferred — отложенную корутину, которую можно запустить позднее.

Dispatchers.IO — один из параметров метода launch(). Здесь указывается диспетчер для созданной корутины. Конкретно диспетчер Dispatchers.IO используется для фоновых задач, не блокирующих основной поток. Если указать Dispatchers.Main, то корутина будет выполняться в основном потоке.

Что имеем в итоге? Простой метод запуска асинхронного кода. Но в этом кусочке кода есть скрытые преимущества , которые не видны на первый взгляд:

  • корутины легковесны. Аналогичный код с созданием и запуском потока потребует много больше памяти:

Корутины же мы можем создавать тысячами;

  • корутину можно приостановить . Метод delay(timeout) приостановит выполнение корутины, но это никак не отразится на потоке, в котором она выполняется;
  • в отличие от RxJava, для написания асинхронного кода не надо заучивать массу операторов типа merge, zip, andThen map, flatMap и т.д. Можно просто писать код, который будет запущен асинхронно, используя минимум дополнительных методов. Для реализации более сложной логики можно применять уже знакомые языковые конструкции, такие как foreach, repeat, filter и т.д.

Когда нужен асинхронный подход

Вернемся к нашей задаче использования корутин. Приложение под Android, над которым мы сейчас работаем, общается с сервером и хранит информацию в базе данных. На первый взгляд, ничего нового по функционалу, но интересен сам подход в реализации, поскольку тестируем новый инструмент разработки асинхронного кода — корутины Kotlin.

В своем приложении мы применяем асинхронный код. Почему? Дело в том, что общение с сервером и запросы в базу данных — довольно продолжительные операции. Пока выполняется одна, вполне можно успеть завершить еще несколько, не блокируя основной поток. Именно эту задачу и решает асинхронный подход. В случае синхронного программирования операции выполняются последовательно, т.е. следующая команда запускается только после того, как завершится предыдущая, и когда какая-нибудь из них выполняется слишком долго, программа может зависнуть. И хотя все понимают, что “зависание” вряд ли понравится пользователям, все же такую реализацию иногда можно встретить в приложениях. Повторюсь, мы решаем задачу с помощью асинхронного кода.

Применение Coroutines Kotlin в нашем проекте

Итак, запуск абстрактного асинхронного кода — это хорошо, но попробуем решить более насущную задачу. Допустим, надо сделать запрос на сервер и показать результат. Посмотрим, как это можно сделать с помощью корутин. Само скачивание будем для простоты выполнять во ViewModel, общаться с Activity будем с помощью LiveData.

Читайте также:  Root app delete для андроид 10

Создадим класс-наследник ViewModel :

Внутри модель содержит MutableLiveData с данными пользователя, который мы получаем после авторизации. Наружу отдаем неизменяемую LiveData, чтобы никто кроме ViewModel не мог изменять данные внутри. Профиль пользователя завернут в класс Resource<>. Это утилитарный класс для удобства передачи состояния процесса во View:

Как видно, во View мы можем передавать информацию о том, завершилось ли скачивание, и если завершилось, то с ошибкой или успешно.

Запуск корутины происходит в методе login() . Он вызывает метод базового класса runCoroutine() :

У этого метода 2 параметра. Первый — типизированный экземпляр LiveData, куда будут записаны данные. Второй — код, который нужно выполнить асинхронно. В методе login() мы передаем код, который передает на сервер данные для авторизации и получает от сервера профиль пользователя.

Как работает все вместе : View получает от ViewModel LiveData, подписывается на ее изменения. Изменения могут быть трех видов: идет какой-то процесс, все завершилось с ошибкой, все завершилось успешно. В нужный момент вызывается метод login(). Затем последовательно происходит: запись в LiveData информации о том, что “идет какой-то процесс”, запрос на сервер, получение данных, запись в LiveData полученных данных. Или ошибки, если запрос на сервер не удался.

Выводы

Естественно, в одной статье невозможно раскрыть все аспекты нового инструмента в асинхронном программировании. Тем, кто заинтересовался корутинами Kotlin , можно посоветовать изучить и протестировать, к примеру, комбинирование корутин, каналы, реализацию Actor model и другие возможности.

Несмотря на то, что в рамках примера показана довольно банальная задача — скачать данные с сервера, что делается почти в каждом приложении, он иллюстрирует принцип работы с корутинами. Вместо скачивания может быть что угодно. Пример показывает, как с помощью корутин удобно обернуть любую операцию.

Как мы видим, задачи асинхронного программирования под Android проще реализовать с помощью корутин : быстрее разработка, выше читаемость кода. Риски, конечно, тоже есть : для изучения корутин нужно некоторое время, а их возможности иногда могут не закрыть все требования задачи. Перед использованием в своем проекте рекомендуется внимательно ознакомиться с областью их применения.

Источник

Как использовать Котлин корутины (Kotlin Coroutines) в андроид приложении. Часть 1

Это первый курок курса о том, как использовать Котлин корутины в андроид приложении.

В этом курсе вы узнаете, как использовать Kotlin Coroutines в приложении для Android — новый способ управления фоновыми потоками (background threads), который может упростить код за счет уменьшения потребности в обратных вызовах (callbacks). Корутины, или сопрограммы — это функция Kotlin, которая преобразует асинхронные обратные вызовы для длительных задач, таких как доступ к базе данных или сети, в последовательный (sequential) код.

Чтобы на практике увидеть работу с Kotlin Coroutines и архитектурными компонентами, записывайтесь на продвинутый курс по разработке приложения «Чат-мессенжер»

Вот фрагмент кода, чтобы дать вам представление о том, что вы будете делать:

Код на основе обратного вызова будет преобразован в последовательный код с использованием корутин:

Читайте также:  Сканер qr кода для android apk

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

К концу этого курса у вас будет достаточно опыта для преобразования существующего API для использования корутин, и вы сможете интегрировать корутины в приложение. Вы также познакомитесь с лучшими практиками для корутин и с тем, как написать тест для кода, который использует корутины.

Что вы узнаете

  • Как вызвать код, написанный с корутинами и получить результаты.
  • Как использовать функции приостановки (suspend), чтобы сделать асинхронный код последовательным.
  • Как использовать launch и runBlocking для контроля выполнения кода.
  • Методы преобразования существующих API в корутины с использованием suspendCoroutine.
  • Как использовать корутины с Architecture Components.
  • Лучшие практики для тестирования корутин.

Что нужно знать

  • Знакомство с компонентами архитектуры ViewModel , LiveData , Repository , и Room .
  • Знакомство с синтаксисом Kotlin, включая функции расширения (extension) и лямбды.
  • Основное понимание использования потоков в Android, включая основной поток, фоновые потоки и обратные вызовы.

Для ознакомления с синтаксисом Kotlin см. Kotlin Bootcamp for Programmers.

Для ознакомления с основами многопоточности в Android см. Guide to background processing.

Что вам понадобится

Android Studio 3.3 (можно работать с другими версиями, но некоторые вещи могут отсутствовать или выглядеть иначе).

Приступаем к настройке

Исходный код

Нажмите на кнопку, чтобы загрузить весь код для серии уроков:

… или клонируйте GitHub-репозиторий из командной строки, используя следующую команду:

Репозиторий kotlin-coroutines содержит три разных приложения:

  • kotlin-coroutines-start — Простое приложение, чтобы изучить, как сделать свою первую корутину
  • kotlin-coroutines-repository — Проект основан на обратных вызовах, которые вы конвертируете для использования корутин.
  • kotlin-coroutines-end — Проект с корутинами уже добавлен

Запуск приложения

Во-первых, давайте посмотрим, как выглядит исходный пример приложения. Следуйте этим инструкциям, чтобы открыть образец приложения в Android Studio.

  1. Если вы загрузили zip-файл kotlin-coroutines, распакуйте его.
  2. Откройте проект kotlin-coroutines-start в Android Studio.
  3. Нажмите кнопку Run и выберите эмулятор или подключите устройство Android, которое должно поддерживать Android Lollipop (минимальный поддерживаемый SDK — 21). Экран Kotlin Coroutines должен появиться:

Это стартовое приложение использует потоки, чтобы отобразить снэк-бар через секунду после нажатия в любом месте экрана. Попробуйте сейчас, и вы должны увидеть «Hello, from threads!» после небольшой задержки В первой части этого курса вы конвертируете это приложение для использования корутин.

Это приложение использует компоненты архитектуры для отделения кода пользовательского интерфейса в MainActivity от логики приложения в MainViewModel. Найдите минутку, чтобы ознакомиться со структурой проекта.

  1. MainActivity отображает пользовательский интерфейс, регистрирует слушатели кнопок и может отображать Snackbar . Он передает события MainViewModel и обновляет экран на основе LiveData в MainViewModel .
  2. MainViewModel обрабатывает события в onMainViewClicked и будет общаться с MainActivity используя LiveData.
  3. Executors определяет BACKGROUND, который может запускать работу в фоновом потоке.
  4. MainViewModelTest определяет тест для MainViewModel .

Добавление корутин в проект

Чтобы использовать корутины в Kotlin, необходимо включить библиотеку coroutines-core в файл build.gradle (Module: app) вашего проекта. В текущем проекте это уже сделано.

Корутины на Android доступны как базовая библиотека, а также специальные расширения для Android:

  • kotlinx-corountines-core — Основной интерфейс для использования корутин в Kotlin
  • kotlinx-coroutines-android — Поддержка основного потока Android в корутинах

Источник

Android kotlin coroutines gradle

Copy raw contents

Library support for Kotlin coroutines with multiplatform support. This is a companion version for the Kotlin 1.6.0 release.

  • core — common coroutines across all platforms:
    • launch and async coroutine builders returning Job and Deferred light-weight futures with cancellation support;
    • Dispatchers object with Main dispatcher for Android/Swing/JavaFx, and Default dispatcher for background coroutines;
    • delay and yield top-level suspending functions;
    • Flow — cold asynchronous stream with flow builder and comprehensive operator set (filter, map, etc);
    • Channel, Mutex, and Semaphore communication and synchronization primitives;
    • coroutineScope, supervisorScope, withContext, and withTimeout scope builders;
    • MainScope() for Android and UI applications;
    • SupervisorJob() and CoroutineExceptionHandler for supervision of coroutines hierarchies;
    • select expression support and more.
  • core/jvm — additional core features available on Kotlin/JVM:
    • Dispatchers.IO dispatcher for blocking coroutines;
    • Executor.asCoroutineDispatcher extension, custom thread pools, and more.
  • core/js — additional core features available on Kotlin/JS:
    • Integration with Promise via Promise.await and promise builder;
    • Integration with Window via Window.asCoroutineDispatcher, etc.
  • test — test utilities for coroutines:
    • Dispatchers.setMain to override Dispatchers.Main in tests;
    • TestCoroutineScope to test suspending functions and coroutines.
  • debug — debug utilities for coroutines:
    • DebugProbes API to probe, keep track of, print and dump active coroutines;
    • CoroutinesTimeout test rule to automatically dump coroutines on test timeout.
    • Automatic integration with BlockHound.
  • reactive — modules that provide builders and iteration support for various reactive streams libraries:
    • Reactive Streams (Publisher.collect, Publisher.awaitSingle, kotlinx.coroutines.reactive.publish, etc),
    • Flow (JDK 9) (the same interface as for Reactive Streams),
    • RxJava 2.x (rxFlowable, rxSingle, etc), and
    • RxJava 3.x (rxFlowable, rxSingle, etc), and
    • Project Reactor (flux, mono, etc).
  • ui — modules that provide coroutine dispatchers for various single-threaded UI libraries:
    • Android, JavaFX, and Swing.
  • integration — modules that provide integration with various asynchronous callback- and future-based libraries:
    • JDK8 CompletionStage.await, Guava ListenableFuture.await, and Google Play Services Task.await;
    • SLF4J MDC integration via MDCContext.
  • Presentations and videos:
    • Introduction to Coroutines (Roman Elizarov at KotlinConf 2017, slides)
    • Deep dive into Coroutines (Roman Elizarov at KotlinConf 2017, slides)
    • Kotlin Coroutines in Practice (Roman Elizarov at KotlinConf 2018, slides)
  • Guides and manuals:
    • Guide to kotlinx.coroutines by example (read it first)
    • Guide to UI programming with coroutines
    • Debugging capabilities in kotlinx.coroutines
  • Compatibility policy and experimental annotations
  • Change log for kotlinx.coroutines
  • Coroutines design document (KEEP)
  • Full kotlinx.coroutines API reference
Читайте также:  Аналог плеймаркета для андроид пиратка

Using in your projects

Add dependencies (you can also add other modules that you need):

And make sure that you use the latest Kotlin version:

Add dependencies (you can also add other modules that you need):

And make sure that you use the latest Kotlin version:

Make sure that you have mavenCentral() in the list of repositories:

Gradle Kotlin DSL

Add dependencies (you can also add other modules that you need):

And make sure that you use the latest Kotlin version:

Make sure that you have mavenCentral() in the list of repositories.

Add kotlinx-coroutines-android module as a dependency when using kotlinx.coroutines on Android:

This gives you access to the Android Dispatchers.Main coroutine dispatcher and also makes sure that in case of a crashed coroutine with an unhandled exception that this exception is logged before crashing the Android application, similarly to the way uncaught exceptions in threads are handled by the Android runtime.

R8 and ProGuard

R8 and ProGuard rules are bundled into the kotlinx-coroutines-android module. For more details see «Optimization» section for Android.

Avoiding including the debug infrastructure in the resulting APK

The kotlinx-coroutines-core artifact contains a resource file that is not required for the coroutines to operate normally and is only used by the debugger. To exclude it at no loss of functionality, add the following snippet to the android block in your Gradle file for the application subproject:

Core modules of kotlinx.coroutines are also available for Kotlin/JS and Kotlin/Native.

In common code that should get compiled for different platforms, you can add a dependency to kotlinx-coroutines-core right to the commonMain source set:

No more additional dependencies are needed, platform-specific artifacts will be resolved automatically via Gradle metadata available since Gradle 5.3.

Platform-specific dependencies are recommended to be used only for non-multiplatform projects that are compiled only for target platform.

Kotlin/JS version of kotlinx.coroutines is published as kotlinx-coroutines-core-js (follow the link to get the dependency declaration snippet) and as kotlinx-coroutines-core NPM package.

Kotlin/Native version of kotlinx.coroutines is published as kotlinx-coroutines-core-$platform where $platform is the target Kotlin/Native platform. List of currently supported targets.

Only single-threaded code (JS-style) on Kotlin/Native is supported in stable versions. Additionally, a special -native-mt version is released on a regular basis, for the state of multi-threaded coroutines support please follow the corresponding issue for the additional details.

Источник

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