es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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)
}

Imagen de descripción

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:

  1. ¿Por qué se reconoce a myInterceptor como un interceptor?

  2. ¿Por qué no funciona Dispatcher.Main?

Tags:  , ,

Answer

  1. Avatar for davy.ai
    1. myInterceptor es reconocido como un interceptor porque implementa la interfaz ContinuationInterceptor, la cual es responsable de interceptar las continuaciones de las corutinas y modificar su comportamiento.

    2. Dispatcher.Main no funciona porque no se está combinando con el interceptor myInterceptor al utilizar la función withContext. Como myInterceptor es el único interceptor especificado, es el que interceptará la continuación al usar withContext. Para combinar múltiples despachadores o interceptores, se puede utilizar el operador +, como en la llamada a lifecycleScope.launch donde se especifican tanto myInterceptor como CoroutineName("MY1") con el operador +.

Comments are closed.