Kotlin: Sincronizar hilo con Coroutine
Actualmente tengo un hilo principal que buclea constantemente:
var suspension = Suspension()
fun loop() {
// Haciendo cosas aquí...
suspension.callTick()
// Haciendo más cosas aquí...
}
Llama al método callTick() que envía datos a un canal:
class Suspension {
private val ticksChannel = Channel<unit>(0)
fun callTick() {
ticksChannel.trySend(Unit)
}
suspend fun waitTick() {
ticksChannel.receive()
}
}
Ahora mi última clase hace uso de esto:
class Task(private val suspension: Suspension) {
suspend fun runTask() {
while (true) {
suspension.waitTick()
someMethodOnTheMainThread()
}
}
}
Ahora me pregunto cómo puedo llamar al método someMethodOnTheMainThread() desde el hilo principal. La función debe ser llamada justo después del método ‘suspension.callTick()’ en loop(). En este momento estoy ejecutando la función desde el hilo de la hebra asíncrona. Esto causa muchos errores y excepciones de puntero nulo porque no está sincronizado con el hilo principal.
Básicamente me pregunto cómo bloquear / bloquear el hilo principal hasta que se llame al método suspension.waitTick() y se ejecute el código posterior. ¿Es esto demasiado complejo? ¿Hay otra forma de hacer que las funciones de suspensión funcionen con código sincronizado?
davy.ai
Como experto en concurrencia y corrutinas en Kotlin, hay algunas soluciones a considerar para llamar a un método desde el hilo principal justo después del método
suspension.callTick()
enloop()
:runOnUiThread()
: Si estás trabajando con una aplicación de Android, puedes utilizar el métodorunOnUiThread()
para ejecutar código en el hilo principal. Dado queloop()
se ejecuta en el hilo principal, puedes llamar directamente a este método para ejecutarsomeMethodOnTheMainThread()
justo después desuspension.callTick()
.GlobalScope.launch
: Otra opción es lanzar una corrutina en el hilo principal utilizandoGlobalScope.launch
. Dado queloop()
se ejecuta en el hilo principal, puedes lanzar una nueva corrutina que ejecutarásomeMethodOnTheMainThread()
después desuspension.callTick()
.Handler
para publicar unRunnable
: También puedes utilizar unHandler
para publicar unRunnable
en la cola de mensajes del hilo principal. Una vez más, dado queloop()
se ejecuta en el hilo principal, puedes crear unHandler
y utilizarlo para publicar unRunnable
que ejecutesomeMethodOnTheMainThread()
después desuspension.callTick()
.En cuanto a bloquear o detener el hilo principal hasta que se llame a
suspension.waitTick()
y se ejecute el código posterior a él, esto no se recomienda, ya que podría hacer que la aplicación se bloquee. Las corrutinas y las funciones de suspensión están diseñadas para trabajar de forma asíncrona y sin bloquear el hilo principal. En su lugar, debes utilizar una de las soluciones mencionadas anteriormente para ejecutar tu código en el hilo principal cuando sea necesario.