Como estamos usando Coroutines (1.3.5 usado) tenemos muchos bloqueos: JobCancellationException - StandaloneCoroutine fue cancelado .
Leí muchos hilos sobre estos problemas y probé muchas soluciones en producción, pero siempre ocurren fallas.
En todos nuestros modelos de vista estamos usando el viewmodelscope así que está bien.
Pero en nuestra capa de datos necesitamos lanzar eventos de seguimiento que son una tarea de disparar y olvidar . En el primer paso usamos un GlobalScope.launch . Estaba pensando que CancelletationException se debía a este alcance global, así que lo eliminé y creé una extensión en la capa de datos usando un SupervisorJob y un CoroutineExceptionHandler :
private val appScope = CoroutineScope(Dispatchers.Default + SupervisorJob()) private val coroutineExceptionHandler by lazy { CoroutineExceptionHandler { _, throwable -> logw("Error occurred inside Coroutine.", throwable) } } fun launchOnApp(block: suspend CoroutineScope.() -> Unit) { appScope.launch(coroutineExceptionHandler) { block() } } Pero siempre vi fallas con este código. ¿Necesito usar el método cancelAndJoin ? ¿Qué estrategia puedo usar con un archi limpio y este tipo de trabajo, por favor?
Gracias por adelantado
Puede crear una utilidad de extensión que detecte la excepción de cancelación y haga lo que quiera con ella:
fun CoroutineScope.safeLaunch(block: suspend CoroutineScope.() -> Unit): Job { return this.launch { try { block() } catch (ce: CancellationException) { // You can ignore or log this exception } catch (e: Exception) { // Here it's better to at least log the exception Log.e("TAG","Coroutine error", e) } } }Y puede usar la extensión con el alcance de la rutina de su elección, por ejemplo, el alcance global:
GlobalScope.safeLaunch{ // here goes my suspend functions and stuff }o cualquier alcance del modelo de vista:
myViewModel.viewModelScope.safeLaunch{ // here goes my suspend functions and stuff }