Introducció

Les coroutines són una característica poderosa de Kotlin que permeten escriure codi asíncron de manera més senzilla i llegible. A diferència dels fils (threads), les coroutines són lleugeres i poden ser suspeses i reprèses sense bloquejar el fil en què s'executen. Això les fa ideals per a operacions d'entrada/sortida (I/O) i altres tasques que poden trigar temps a completar-se.

Conceptes Clau

  1. Coroutines

  • CoroutineScope: Defineix l'àmbit en què s'executen les coroutines.
  • launch: Inicia una nova coroutine.
  • async: Inicia una nova coroutine i retorna un resultat diferit (Deferred).
  • suspend: Marca una funció com a suspesa, permetent que la coroutine es suspengui i reprengui.

  1. Builders de Coroutines

  • runBlocking: Bloqueja el fil actual fins que totes les coroutines completes dins del seu àmbit.
  • launch: Inicia una nova coroutine sense retornar cap resultat.
  • async: Inicia una nova coroutine i retorna un Deferred, que pot contenir un resultat.

  1. Context de Coroutines

  • Dispatchers: Defineixen en quin fil o grup de fils s'executarà la coroutine.
    • Dispatchers.Main: Utilitzat per a operacions de la interfície d'usuari.
    • Dispatchers.IO: Optimitzat per a operacions d'entrada/sortida.
    • Dispatchers.Default: Utilitzat per a tasques intensives en CPU.

Exemples Pràctics

Exemple 1: Lançar una Coroutine

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000L)
        println("Hola, Coroutine!")
    }
    println("Hola, Món!")
}

Explicació:

  • runBlocking: Bloqueja el fil principal fins que totes les coroutines completes.
  • launch: Inicia una nova coroutine.
  • delay: Suspèn la coroutine durant 1 segon.

Exemple 2: Utilitzar async per a Tasques Concurrent

import kotlinx.coroutines.*

fun main() = runBlocking {
    val deferred1 = async { fetchDataFromNetwork() }
    val deferred2 = async { fetchDataFromDatabase() }
    
    val result1 = deferred1.await()
    val result2 = deferred2.await()
    
    println("Resultat: $result1 i $result2")
}

suspend fun fetchDataFromNetwork(): String {
    delay(1000L) // Simula una operació de xarxa
    return "Dades de la Xarxa"
}

suspend fun fetchDataFromDatabase(): String {
    delay(500L) // Simula una operació de base de dades
    return "Dades de la Base de Dades"
}

Explicació:

  • async: Inicia una nova coroutine i retorna un Deferred.
  • await: Espera el resultat de la coroutine.

Exercicis Pràctics

Exercici 1: Crear una Coroutine Simple

Descripció: Crea una funció que llança una coroutine que imprimeix un missatge després d'un retard de 2 segons.

Solució:

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(2000L)
        println("Missatge després de 2 segons")
    }
    println("Missatge immediat")
}

Exercici 2: Utilitzar async per a Tasques Paral·leles

Descripció: Crea dues funcions suspeses que simulen operacions de xarxa i base de dades. Utilitza async per executar-les en paral·lel i imprimeix els resultats.

Solució:

import kotlinx.coroutines.*

fun main() = runBlocking {
    val networkData = async { simulateNetworkOperation() }
    val databaseData = async { simulateDatabaseOperation() }
    
    println("Resultat de la Xarxa: ${networkData.await()}")
    println("Resultat de la Base de Dades: ${databaseData.await()}")
}

suspend fun simulateNetworkOperation(): String {
    delay(1000L)
    return "Dades de la Xarxa"
}

suspend fun simulateDatabaseOperation(): String {
    delay(500L)
    return "Dades de la Base de Dades"
}

Errors Comuns i Consells

Errors Comuns

  • No utilitzar suspend en funcions que criden delay o altres funcions suspeses.
  • Oblidar await en coroutines llançades amb async, el que pot provocar que el resultat no es recuperi.

Consells

  • Utilitza Dispatchers.IO per a operacions d'entrada/sortida per evitar bloquejar el fil principal.
  • Utilitza Dispatchers.Main per a operacions de la interfície d'usuari per assegurar que les actualitzacions es facin en el fil principal.

Conclusió

Les coroutines de Kotlin proporcionen una manera eficient i llegible de gestionar la programació asíncrona. Amb els conceptes i exemples presentats, hauríeu de ser capaços de començar a utilitzar coroutines en les vostres aplicacions per millorar el rendiment i la resposta. En el següent mòdul, explorarem com utilitzar aquestes tècniques en el desenvolupament d'aplicacions Android.

© Copyright 2024. Tots els drets reservats