Coroutines sous Android

Jan 29 2023
Que sont les coroutines ? Les coroutines aident à gérer les tâches de longue durée qui pourraient autrement bloquer le thread principal et empêcher votre application de répondre. Une coroutine est un modèle de conception de concurrence que vous pouvez utiliser sur Android pour simplifier le code qui s'exécute de manière asynchrone.

Que sont les coroutines ?

Les coroutines aident à gérer les tâches de longue durée qui pourraient autrement bloquer le thread principal et empêcher votre application de répondre. Une coroutine est un modèle de conception de concurrence que vous pouvez utiliser sur Android pour simplifier le code qui s'exécute de manière asynchrone.

Comme vous le voyez dans le diagramme ci-dessus, dans votre thread principal, vous ne pouvez effectuer que de petites opérations. Si vous souhaitez effectuer des opérations de longue durée dans votre thread principal, votre application risque de planter et de ralentir. Ou si vous créez non. de thread d'arrière-plan / de travail, puis un problème de mémoire est à venir. Les coroutines sont un type spécial de fonction qui cède délibérément le contrôle à l'appelant, mais ne met pas fin à son contexte dans le processus, mais le maintient à l'état inactif.

Comment utiliser les coroutines ?

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:x.x.x"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:x.x.x"
}

  • Principal : utilise le fil d'interface utilisateur. Dans Rx est similaire à AndroidSchedulers.MainThread()
  • Par défaut : utilisé pour les tâches gourmandes en CPU . Il utilisera autant de threads que de cœurs de processeur disponibles. Puisqu'il s'agit de tâches gourmandes en CPU, il est inutile d'avoir plusieurs threads en cours d'exécution, car le CPU va être occupé. Similaire à Schedulers.computation() dans Rx.
  • IO : utilisé pour l'entrée/la sortie. Faire une demande à une API, accéder à une base de données, etc. Similaire à Schedulers.io() dans Rx.
  • Travail : il s'agit essentiellement d'une tâche qui s'exécute en arrière-plan et qui peut être interprétée comme une action, avec un cycle de vie qui est détruit une fois terminé.
  • Pour exécuter différentes opérations à l'aide de travaux : Job.join
  • Pour annuler tous les travaux enfants : Job.cancel
  • withContext : une autre façon d'écrire l'async où nous n'avons pas à écrire await().
  • suspend fun fetchUser() = withContext(Dispatchers.IO) {
            // make network call
            // return 
    }
    

Suspendre : Comme leur nom l'indique, ce sont des fonctions qui suspendent l'exécution d'une coroutine à un moment donné, puis reprennent l'exécution de la fonction lorsque le résultat est prêt.

suspend fun makeNetworkRequest() {
    // fetchData is another suspend function, so 'makeNetworkRequest' is going to be `suspended`
    // until it's result becomes available, without blocking the main thread.
    val result = fetchData()
    // continues executing once the result becomes available
    show(result)
}

// fetchData is main thread safe
suspend fun fetchData(): Result { ... }

Le lancement ne bloquera pas le thread principal, mais d'un autre côté, l'exécution de la partie restante du code n'attendra pas le résultat du lancement puisque le lancement n'est pas un appel de suspension.

fun GFG()
{
    var resultOne = "Android"
    var resultTwo = "Kotlin"
    Log.i("Launch", "Before")
    launch(Dispatchers.IO) { resultOne = function1() }
    launch(Dispatchers.IO) { resultTwo = function2() }
    Log.i("Launch", "After")
    val resultText = resultOne + resultTwo
    Log.i("Launch", resultText)
}

suspend fun function1(): String
{
    delay(1000L)
    val message = "function1"
    Log.i("Launch", message)
    return message
}

suspend fun function2(): String
{
    delay(100L)
    val message = "function2"
    Log.i("Launch", message)
    return message
}

Async est également utilisé pour démarrer les coroutines, mais il bloque le thread principal au point d'entrée de la fonction await() dans le programme.

fun GFG
{
    Log.i("Async", "Before")
    val resultOne = Async(Dispatchers.IO) { function1() }
    val resultTwo = Async(Dispatchers.IO) { function2() }
    Log.i("Async", "After")
    val resultText = resultOne.await() + resultTwo.await()
    Log.i("Async", resultText)
}

suspend fun function1(): String
{
    delay(1000L)
    val message = "function1"
    Log.i("Async", message)
    return message
}

suspend fun function2(): String
{
    delay(100L)
    val message = "function2"
    Log.i("Async", message)
    return message
}

Avantages de l'utilisation de Coroutines

  • Les coroutines sont des threads légers
  • Les coroutines peuvent fonctionner en parallèle, s'attendre et communiquer entre elles
  • Créez des milliers de coroutines sans aucun problème de mémoire
  • Idéal pour les applications modernes