Как проверить состояние джобы в корутинах
Что проверяют
Понимаете ли вы жизненный цикл Job и то, что отмена в корутинах кооперативная. Сами флаги интересуют интервьюера меньше, чем их применение: как не запустить второй запрос, пока жив первый, и как корректно остановить работу. Следом обычно спрашивают, чем отмена отличается от ошибки и что будет, если поймать CancellationException.
Как отвечать
launch возвращает Job с тремя флагами:
isActive: корутина запущена, ещё не завершилась и не отменяется;isCompleted: работа закончилась любым способом: успехом, ошибкой или отменой;isCancelled: отмена запрошена явно или вызвана исключением, флаг поднимается уже во время отмены.
За флагами стоят состояния: New (только при CoroutineStart.LAZY до вызова start()), Active, Completing, пока ждут дочерние корутины, Cancelling и конечные Completed и Cancelled. Важное следствие: isCompleted равен true и после отмены, поэтому исход различают по isCancelled или по причине в invokeOnCompletion { cause -> }.
Практика в Android:
- повторный запуск: держите во ViewModel
private var searchJob: Job? = null, перед новым поиском вызывайтеsearchJob?.cancel()и запускайте заново черезviewModelScope.launch; - внутри корутины: в долгом вычислении проверяйте
isActiveили вызывайтеensureActive(), иначеcancel()не остановит код без точек приостановки; - ожидание:
join()ждёт завершения,cancelAndJoin()отменяет и ждёт.
Для интерфейса флаги Job не опрашивают. Состояние загрузки ViewModel отдаёт через StateFlow, а Job остаётся инструментом управления работой.
Где спотыкаются
Запускают корутины в GlobalScope, как в старых примерах. Такая работа не привязана к жизненному циклу экрана и продолжается после его закрытия.
Ловят всё через catch (e: Exception) и глотают CancellationException. Корутина продолжает работу после отмены, и структурная конкурентность ломается.
Считают isCompleted признаком успеха и показывают «Готово» после отмены.