← Назад к вопросам
Для чего нужен 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
| Способ | Возвращает | Результат | Ошибки |
|---|---|---|---|
| launch | Job | Нет | Нужен try-catch |
| async | Deferred<T> | Есть (await()) | Выбрасывает на await() |
| Job | Job | Нет |
Иерархия 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 нужен для:
- Отслеживания состояния корутины
- Отмены (явной или по жизненному циклу)
- Ожидания завершения
- Иерархии корутин (родитель отменяет детей)
- Правильной очистки ресурсов при уничтожении компонентов