Interceptores personalizados en corrutinas
Me he familiarizado con la sección de ContinuationInterceptor
de las coroutines. Escribí la siguiente sección de código para verificar mi idea.
class MyContext: CoroutineContext.Element{
override val key : CoroutineContext.Key<*>
get() = object : CoroutineContext.Key<MyContext>{}
}
val myInterceptor = object : ContinuationInterceptor {
//La clave se establece como un tipo no interceptor
override val key : CoroutineContext.Key<MyContext>
get() = object : CoroutineContext.Key<MyContext>{}
override fun <T> interceptContinuation(continuation:
Continuation<T>): Continuation<T> {
Log.i(TAG,"interceptor:"+continuation.context[CoroutineName].toString())
return Continuation(EmptyCoroutineContext) {
thread(name = "myThread") {
continuation.resumeWith(it)
}
}
}
}
lifecycleScope.launch(myInterceptor + CoroutineName("MY1")) {
Log.i(TAG,"MY1 start:"+Thread.currentThread().name)
fun1()
launch(CoroutineName("MY2")) {
Log.i(TAG,"MY2 run:"+Thread.currentThread().name)
}
withContext(Dispatchers.Main+CoroutineName("MY3")) {
Log.i(TAG,"MY3 run:"+Thread.currentThread().name)
}
Log.i(TAG,"MY1 end:"+Thread.currentThread().name)
}
No tengo la clave de myInterceptor
especificada como ContinuationInterceptor.Key
.
Por lo tanto, las coroutines no deberían reconocerlo como un Interceptor.
MY1
y MY2
demuestran esta idea, pero MY3
es interceptado por myInterceptor
y se ejecuta en un nuevo hilo.
Me pregunto:
-
¿Por qué se reconoce a
myInterceptor
como un interceptor? -
¿Por qué no funciona
Dispatcher.Main
?
davy.ai
myInterceptor
es reconocido como un interceptor porque implementa la interfazContinuationInterceptor
, la cual es responsable de interceptar las continuaciones de las corutinas y modificar su comportamiento.Dispatcher.Main
no funciona porque no se está combinando con el interceptormyInterceptor
al utilizar la funciónwithContext
. ComomyInterceptor
es el único interceptor especificado, es el que interceptará la continuación al usarwithContext
. Para combinar múltiples despachadores o interceptores, se puede utilizar el operador+
, como en la llamada alifecycleScope.launch
donde se especifican tantomyInterceptor
comoCoroutineName("MY1")
con el operador+
.