← Назад к вопросам

Для чего нужен Job в Coroutines?

2.3 Middle🔥 211 комментариев
#Kotlin основы#Многопоточность и асинхронность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Назначение Job в Kotlin Coroutines

Job — это основной строительный блок для управления жизненным циклом корутин. Это дескриптор, который представляет объект сопрограммы и позволяет её контролировать.

Основные функции Job

1. Отслеживание состояния корутины

val job = GlobalScope.launch {
    delay(1000)
    println("Выполнено")
}

println(job.isActive)    // true
println(job.isCompleted) // false
println(job.isCancelled) // false

// После выполнения:
// isActive = false, isCompleted = true, isCancelled = false

2. Отмена корутины (Cancellation)

val job = launch {
    repeat(100) { i ->
        println("Work $i")
        delay(1000)
    }
}

delay(5000)
job.cancel() // Отменяет корутину

// Или
job.cancelAndJoin() // Отменить и дождаться завершения

3. Ожидание завершения (Suspension)

val job = launch {
    println("Начало")
    delay(2000)
    println("Конец")
}

println("До join")
job.join() // Блокирует текущую корутину до завершения job
println("После join") // Выпечатается только после завершения job

Job vs Launch vs Async

СпособВозвращаетРезультатОшибки
launchJobНетНужен try-catch
asyncDeferred<T>Есть (await())Выбрасывает на await()
JobJobНет

Иерархия Job

Job образует родительско-дочерние отношения:

val parentJob = Job()
val scope = CoroutineScope(Dispatchers.Main + parentJob)

scope.launch {
    println("Child 1")
}

scope.launch {
    println("Child 2")
}

parentJob.cancel() // Отменит ВСЕ дочерние корутины

Обработка отмены (CancellationException)

val job = launch {
    try {
        repeat(1000) {
            delay(100) // Точка отмены
            println("Iteration $it")
        }
    } catch (e: CancellationException) {
        println("Корутина отменена")
        throw e // ВАЖНО: пробросить дальше!
    } finally {
        println("Очистка ресурсов")
    }
}

job.cancel()

Практические примеры

1. Отмена при уничтожении Activity

class MyActivity : AppCompatActivity() {
    private val job = Job()
    private val scope = CoroutineScope(Dispatchers.Main + job)
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        scope.launch {
            val data = loadData() // Сетевой запрос
            updateUI(data)
        }
    }
    
    override fun onDestroy() {
        super.onDestroy()
        job.cancel() // Отменяет все корутины при уничтожении Activity
    }
}

2. viewModelScope (встроенный Job в ViewModel)

class MyViewModel : ViewModel() {
    fun loadData() {
        viewModelScope.launch {
            // Job автоматически отменяется при уничтожении ViewModel
            val data = repository.getData()
            state.value = data
        }
    }
}

3. Ограничение времени выполнения

val job = launch {
    delay(5000)
    println("Выполнено")
}

launchMain {
    delay(2000)
    job.cancel() // Отменить через 2 секунды
}

Job состояния

New → Active → Completing → Completed
      ↓
      Cancelling → Cancelled
  • New: Создана, но ещё не запущена
  • Active: Выполняется
  • Completing: Завершает дочерние корутины
  • Completed: Закончена без ошибок
  • Cancelling: Процесс отмены
  • Cancelled: Отменена

Методы Job

job.start()           // Запустить корутину
job.join()            // Ждать завершения
job.cancel()          // Отменить
job.cancelAndJoin()   // Отменить и ждать
job.invokeOnCompletion { cause -> } // Колбэк при завершении

Итог

Job нужен для:

  • Отслеживания состояния корутины
  • Отмены (явной или по жизненному циклу)
  • Ожидания завершения
  • Иерархии корутин (родитель отменяет детей)
  • Правильной очистки ресурсов при уничтожении компонентов
Для чего нужен Job в Coroutines? | PrepBro