¿Cómo usar las corrutinas en una aplicación?

¿Cómo voy a usar las corrutinas en mi aplicación?

TL; DR

  • Evita a toda costa usar GlobalScope, no te compliques la vida creando scopes tú mismo y hazte un favor y ejecútalo todo con viewModelScope.launch().
  • Si tienes que volver al hilo principal, usa un LiveData.

En Android tendrás casi el 100% de las veces uno de estos dos escenarios:

  • Solo petición: quieres ejecutar un código y no hay nada que hacer después, no importa si falla, si no falla... Quiero lanzarlo y olvidarme.
  • Petición y respuesta: quieres solicitar datos y pintarlos cuando lleguen, o ejecutar algo y hacer un cambio en la UI cuando termine.

Para ninguno de estos casos te interesa usar lifecycleScope, ya que tus peticiones no deberían verse afectadas por los cambios de configuración de la activity. Si declaras las peticiones en el onCreate(), se estarían destruyendo y lanzando una y otra vez cada vez que girases la pantalla. Así que no quieres usar ese ámbito. Este problema lo solucionas con viewModelScope.

Solo petición

Si solo tienes que ejecutar un código y olvidarte, usa viewModelScope con el dispatcher Dispatchers.IO o Dispatchers.Default según te convenga, para ejecutar el código en un hilo secundario:

fun sendMessage(message: String) {
    viewModelScope.launch(Dispatchers.IO) {
      // Aquí estamos en un hilo secundario, así que hacemos el trabajo
      repository.sendMessage(message)
    }
}

Este método envía un mensaje y no necesita hacer nada después. Si el mensaje se envía o no, no nos importa. Por ello, no hacemos nada después de llamar.

Petición y respuesta

Sin embargo, si lo que necesitas es obtener datos y pintar algo en pantalla, tienes que obtenerlos en segundo plano y luego cambiar de contexto para volver al hilo principal y pintarlos.

LO MÁS SEGURO SIEMPRE es lanzar corrutinas con el viewModelScope y volver con un live data y olvidarte de paparruchas. Hasta ahora, para salir del segundo plano se utilizaba un Handler (como indicaba Android en su momento, pero gracias al LiveData, ya no hace falta).

Así que, igual que antes, usa Dispatchers.IO o Dispatchers.Default según te convenga, para llevar la ejecución a un hilo secundario, y cuando termines llama al método postValue() de LiveData, que es quien se encarga de informar del valor en primer plano:

fun requestBooks() {
    viewModelScope.launch(Dispatcher.IO) {
      val libros = getLibros()
      liveData.postValue(libros)
    }
}

Es tan simple como esto, pero puedes decidir (o necesitar) complicarte la vida cambiando de contexto.

Comentarios

Entradas populares de este blog

Funciones de suspensión

Tratamiento de excepciones en las corrutinas

Venga, explícame cómo se usan