Recientemente, actualicé Kotlin Coroutines de experimental a 1.1.1 y enfrenté el problema de que job.cancel() en la nueva versión funciona de manera diferente.
Aquí está el código con rutinas experimentales:
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 = this@runAsync.await() onSuccess(result) } catch (e: Exception) { onFailed(e.message) } } }Aquí está con 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) { this@runAsync.await() } onSuccess(result) } catch (e: Exception) { onFailed(e.message) } } }Por ejemplo:
Mi fragmento se destruyó y llamó job.cancel() durante la ejecución de la rutina.
En las corrutinas experimentales no se llamará a onSuccess() ni onFailed() .
En 1.1.1: se llamó a onFailed() porque se JobCancellationException
Me di cuenta de agregar catch (e: JobCancellationException) , pero es imposible:
/** * @suppress **This an internal API and should not be used from general code.** */ internal expect class JobCancellationException( Entonces, la pregunta es: ¿Cómo manejar/ignorar JobCancellationException ?
En su lugar, intenta capturar la CancellationException de superclase, que es parte de la API pública.
Tenga en cuenta que si algo lanza CancellationException , generalmente se espera que lo vuelva a lanzar para que los objetos ascendentes sean notificados sobre la cancelación. Ver La cancelación es cooperativa