Корутины — что это
Корутина (coroutine, по-русски иногда «сопрограмма») — задача, которую можно приостановить и потом продолжить с того же места, не занимая всё это время поток — линию, по которой процессор выполняет команды программы одну за другой. Пока одна корутина ждёт ответа от сервера или чтения файла, на том же потоке выполняются другие.
Зачем это нужно
Многие действия в программе долгие: скачать данные из сети, прочитать большой файл, сходить в базу данных. Если выполнять их «в лоб», программа замрёт до конца операции. В приложении Android это особенно заметно: экран перестаёт отвечать на нажатия, а система может предложить закрыть приложение.
Раньше долгие операции выносили в отдельные потоки (threads) и передавали результат обратно через функции обратного вызова — код получался запутанным. С корутинами тот же код пишется по порядку, сверху вниз, как обычный, а приостановка и продолжение происходят незаметно.
Основные слова
| Слово | Что значит |
|---|---|
suspend fun | функция, которая может приостановиться; вызывается только из корутины или другой suspend-функции |
launch | запустить корутину, результат не нужен («сделай и всё») |
async и await() | запустить корутину, которая вернёт результат, и дождаться его |
delay(1000) | подождать секунду, не занимая поток (в отличие от Thread.sleep) |
runBlocking | запустить корутины из обычного кода и дождаться их конца — для main и тестов |
Dispatchers | где выполнять: Main — поток интерфейса, IO — сеть и файлы, Default — расчёты |
CoroutineScope | «область», которая следит за своими корутинами и может отменить их все разом |
Так выглядит простейшая программа — она печатает Hello, а через секунду World!:
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000L)
println("World!")
}
println("Hello")
}launch запускает корутину, и она сразу засыпает на секунду, а main тем временем печатает Hello.
Что нужно, чтобы попробовать
В сам язык встроены только слово suspend и самые базовые механизмы. launch, async, delay, runBlocking и остальное приходит из отдельной официальной библиотеки JetBrains — kotlinx.coroutines. Её подключают в настройках сборки проекта (Gradle или Maven) как зависимость org.jetbrains.kotlinx:kotlinx-coroutines-core; номер версии берите из официальной документации. Без библиотеки пример выше не соберётся.
Корутины и потоки
- корутина «легче» потока: тысячи корутин работают там, где тысяча потоков уже съела бы много памяти;
- корутины отменяются аккуратно: закрыли экран — отменились все его загрузки;
- ошибка в одной корутине не теряется: её получает область (scope), которая её запустила.
В Android
В приложениях Android корутины — стандартный способ работы с сетью и базой данных. У экранов и моделей экрана есть готовые области: lifecycleScope и viewModelScope — их корутины отменяются сами, когда экран закрыт. Библиотеки Room (база данных) и Retrofit (сеть) умеют работать с suspend-функциями.
Что выучить до корутин
Корутины — тема не для первой недели. Сначала разберитесь с функциями и лямбдами (Функции), классами (Классы, data class и object) и null-безопасностью — в коде с корутинами они встречаются на каждом шагу. Потом — официальное руководство по корутинам на kotlinlang.org (раздел Coroutines документации).