Briefing

En muchas ocasiones en las aplicaciones que desarrollamos, necesitamos realizar operaciones para obtener datos ya sea de nuestra base de datos o de un proveedor externo de manera asíncrona que el usuario interactúa con nuestras vistas.


Para no bloquear el hilo principal de ejecución, la librería de Android nos proporcionaba la clase AsyncTask  con el objetivo de ejecutar estas operaciones en un hilo en segundo plano sin bloquear el main thread donde nuestra vista recibe la información.


El problema de usar AsyncTask es que era realmente pesado para incluso operaciones sencillas. Teníamos que crearlo asociado a un Context lo que nos complicaba realizar tests unitarios a nuestra lógica y además implementar sus callbacks para gestionar el flujo de las operaciones.
Ahora mismo la librería esta prácticamente en desuso y a partir de la API R de Android, estará obsoleta.


El motivo de su caída fue la aparición de ReactiveX, una librería en forma de API que se encargaría de gestionar nuestros hilos de ejecución y realizar estas operaciones asíncronas usando el patrón Observer.


También conocido como Rx, esta librería sigue siendo hoy un standard dentro del desarrollo mobile y sin duda fue un cambio drástico respecto a AsyncTask. Con Rx, lo que haríamos sería ejecutar nuestra lógica dentro de un Observer, al que le asociaríamos un hilo, en nuestro caso el de background para que realicé nuestra lógica bajo él. Además le asociaríamos un hilo de subscripción, normalmente el main thread y por último nos subscribiríamos para recibir actualizaciones del Observer.

Coroutines

Desde que se estableció Kotlin cómo lenguaje de primera clase hace casi 3 años, el término coroutines es algo que siempre estaba por ahí rondando. Como algunos sabréis, coroutines no es algo nuevo en el mundo del software, ya que llevan con nosotros desde hace más de 60 años con el lenguaje ensamblador, pero ¿qué son las coroutines para los androides?

En la documentación oficial podéis ver en detalle, pero en resumen una coroutine es un hilo "ligero" de ejecución, ligero porqué no es que pese menos, bad joke, si no porque en vez crear una tarea cómo sería un Thread corriente cada coroutine es una pequeña tarea que ejecutamos dentro de nuestro hilo y que podemos gestionar junto a otras coroutines o pequeñas tareas en el orden que deseamos.

Esto se consigue a raíz de la keyword suspend. Con esta keyword que la adjuntaremos a nuestra función le estaremos diciendo a nuestro hilo que debe esperarse a que se ejecute para poder seguir con la siguiente operación. La "magia" del suspend es que podemos pedir datos de los que no tenemos control en nuestro servicio como una API o una base de datos y esperar que estas nos devuelvan sus datos para poder seguir con nuestro código, como si le pusiéramos un breakpoint justo a ese línea.

Esto ocurre de esta manera porque la coroutine que estamos ejecutando, por defecto usa el CoroutineBuilder, launch, que nos dice que el código dentro de su ámbito se ejecutará de manera secuencial. Pero, y si ¿quisiéramos ejecutar nuestro código asíncronamente?

Para ello, coroutines nos provee de otro CoroutineBuilder, async, con ello la función suspendida que ejecutemos dentro de él emitirá el retorno de la función dentro de un Deferred, es decir diferido, con esto le estamos diciendo a nuestro código que puede seguir avanzando como haría normalmente mientras que esta función esta ejecutándose en segundo plano.

Ahora si queremos recuperar el retorno de nuestra función tendremos que invocar el método fun.await(). Este método, nos devolverá el objeto encapsulado en el Deferred. En el momento que se invoca esta función, nuestro código vuelve a pararse para poder recibir nuestro objeto.

Conclusión

Pues así por encima estás son las coroutines, este blog lo he hecho a conjunto al evento que mencionaba en el título Lightning Talk: Android, que es un meetup que intento realizar una vez al mes para traer algo de actualidad al mundo androide. En este caso debido a la situación del coronavirus en España hemos tenido que actualizarnos a la era moderna y he realizado un evento en directo donde hablo del tema.

Para entrar más al detalle os dejo los links tanto al repositorio de Github, como las slides que se mostraron durante la transmisión.

PS: También dejo por aquí que se menciono en el directo, la librería para poder tener el scope del ciclo de vida de nuestra vista y tener que usar los CoroutineContext para gestionar los hilos de ejecución

androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0