0Pricing
Android Academy · Урок

Корутины и приостанавливаемые функции

Пишите асинхронный код, который выглядит как синхронный. Используйте приостанавливаемые функции, области корутин и диспетчеры (IO, Main, Default).

«Корутины и приостанавливаемые функции» — бесплатный урок Android Academy на CoddyKit. Это урок 3 из 6. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 6 уроков всего.

Проблема: блокировка потока интерфейса

Android выполняет всю работу интерфейса в главном потоке. Если выполнить сетевой запрос или чтение из базы данных в главном потоке, интерфейс зависнет до завершения операции.

Если интерфейс не отвечает более 5 секунд, Android показывает диалог ANR (приложение не отвечает), и пользователь может принудительно закрыть приложение.

Что такое корутины

Корутины Kotlin позволяют писать асинхронный код, который выглядит последовательным: без callback-функций и цепочек RxJava.

  • Лёгкие — тысячи корутин могут выполняться одновременно
  • Приостанавливаемые — корутина может приостановиться и продолжить работу, не блокируя поток
  • Структурированные — они соблюдают жизненный цикл (область действия)

Функции suspend

Функция с пометкой suspend может приостановить выполнение, не блокируя поток. Её можно вызвать только из другой suspend-функции или области действия корутины.

import kotlinx.coroutines.*

suspend fun fetchData(): String {
    delay(1000)  // simulates 1 second network call
    return "Data loaded!"
}

fun main() = runBlocking {
    println("Fetching...")
    val result = fetchData()  // suspends here, doesn't block
    println(result)           // Data loaded!
    println("Done")
}

Области действия корутин

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

  • viewModelScope — отменяется при очистке ViewModel
  • lifecycleScope — отменяется при уничтожении Activity или Fragment
  • GlobalScope — существует вечно (избегайте его использования)
  • runBlocking — только для тестирования

launch и async

Есть два способа запустить корутину:

  • launch { } — запуск без ожидания результата и без возвращаемого значения
  • async { }.await() — возвращает результат, которого можно дождаться
import kotlinx.coroutines.*

fun main() = runBlocking {
    // launch: no return value
    launch {
        delay(500)
        println("launch done")
    }

    // async: returns a Deferred<T>
    val deferred = async {
        delay(300)
        42
    }
    val result = deferred.await()
    println("async result: $result")
}

Диспетчеры: какой поток?

Dispatchers определяют, в каком потоке или потоках выполняется сопрограмма:

  • Dispatchers.Main — поток пользовательского интерфейса (для обновления представлений)
  • Dispatchers.IO — для сетевых операций и операций с диском
  • Dispatchers.Default — для задач, интенсивно использующих CPU

Используйте withContext(Dispatchers.IO) { }, чтобы переключить диспетчер внутри сопрограммы.

Пример viewModelScope

Загружайте данные в ViewModel, не блокируя пользовательский интерфейс:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*

class DataViewModel : ViewModel() {

    fun loadData() {
        viewModelScope.launch {
            // Switch to IO thread for network
            val data = withContext(Dispatchers.IO) {
                // simulate network request
                delay(1000)
                "Result from server"
            }
            // Back on Main thread — safe to update UI
            _uiState.value = data
        }
    }
}

Обработка ошибок в сопрограммах

Обрабатывайте исключения внутри сопрограммы с помощью try/catch, как и в обычном коде:

viewModelScope.launch {
    try {
        val result = withContext(Dispatchers.IO) {
            api.fetchUser()  // may throw IOException
        }
        _user.value = result
    } catch (e: Exception) {
        _error.value = "Failed: ${e.message}"
    }
}

Параллельные сопрограммы

Запустите две задачи параллельно и дождитесь завершения обеих с помощью async/await:

viewModelScope.launch {
    // Both run at the same time!
    val userDeferred = async(Dispatchers.IO) { api.getUser() }
    val postsDeferred = async(Dispatchers.IO) { api.getPosts() }

    val user = userDeferred.await()
    val posts = postsDeferred.await()

    _state.value = UiState(user, posts)
}

Быстрая проверка

Какой диспетчер сопрограмм следует использовать для сетевых операций и операций с базой данных?

Повторение: сопрограммы

Теперь Вы умеете писать асинхронный код без обратных вызовов:

  • suspend fun — может приостанавливать выполнение, не блокируя поток
  • viewModelScope.launch { } — запускает сопрограмму в ViewModel
  • withContext(Dispatchers.IO) — переключает выполнение на фоновый поток
  • async { }.await() — параллельная работа с результатом
  • try/catch обычно работает и внутри сопрограмм

Далее: шаблон Repository — чёткое разделение источников данных.

Часто задаваемые вопросы

Урок «Корутины и приостанавливаемые функции» бесплатный?

Да — полный текст урока «Корутины и приостанавливаемые функции» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 6 уроков всего.

Чему я научусь в уроке «Корутины и приостанавливаемые функции»?

Пишите асинхронный код, который выглядит как синхронный. Используйте приостанавливаемые функции, области корутин и диспетчеры (IO, Main, Default). Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Android Academy?

Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 6.

Сколько времени занимает урок «Корутины и приостанавливаемые функции»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Android Academy?

Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. ViewModel и LiveData
  2. База данных Room
  3. Корутины и приостанавливаемые функции
  4. Шаблон репозитория
  5. Компонент навигации
  6. Внедрение зависимостей с Hilt
← Назад к Android Academy