Недавно я обновил Kotlin Coroutines с экспериментальной до версии 1.1.1 и столкнулся с проблемой, что job.cancel() в новой версии работает по-другому.
Вот код с экспериментальными сопрограммами:
fun <R : Any, T : Deferred<R>> T.runAsync(
job: Job,
onSuccess: (result: R) -> Unit,
onFailed: (errorMsg: String?) -> Unit) {
launch(UI, parent = job) {
try {
val result = [email protected]()
onSuccess(result)
} catch (e: Exception) {
onFailed(e.message)
}
}
}
Вот с 1.1.1:
fun <R : Any, T : Deferred<R>> T.runAsync(
job: Job,
onSuccess: (result: R) -> Unit,
onFailed: (errorMsg: String?) -> Unit) {
GlobalScope.launch(Dispatchers.Main + job) {
try {
val result = withContext(Dispatchers.IO) {
[email protected]()
}
onSuccess(result)
} catch (e: Exception) {
onFailed(e.message)
}
}
}
Например:
Мой фрагмент уничтожен и вызван job.cancel() во время работы сопрограммы.
В экспериментальных сопрограммах ни onSuccess(), ни onFailed() вызываться не будут.
В 1.1.1: onFailed() вызвали, потому что поймали JobCancellationException
Я придумал добавить catch (e: JobCancellationException), но это невозможно:
/**
* @suppress **This an internal API and should not be used from general code.**
*/
internal expect class JobCancellationException(
Итак, вопрос: как обрабатывать/игнорировать JobCancellationException?
Вместо этого вы пытаетесь поймать суперкласс CancellationException, который является частью общедоступного API.
Обратите внимание, что если что-то бросает CancellationException, вы, как правило, должны повторно выбрасывать его, чтобы вышестоящие объекты были уведомлены об отмене. См. Отмена является совместной