Programmation réactive en Kotlin : de RxKotlin aux coroutines
La programmation réactive est un paradigme orienté vers le traitement asynchrone des flux de données et la propagation des changements. Dans l'écosystème Kotlin, ce concept est implémenté de deux manières principales : via la bibliothèque RxKotlin (extensions réactives pour Kotlin basées sur RxJava) et via le mécanisme intégré des coroutines avec Flow. Dans cet article, nous analyserons en détail les deux approches, leurs caractéristiques et des exemples d'utilisation.
Qu'est-ce que la programmation réactive ?
L'idée principale de la programmation réactive est de travailler avec les données comme des flux continus (streams). Au lieu de demander des données et d'attendre une réponse, vous vous abonnez au flux et réagissez à chaque nouvel événement. Cela est particulièrement utile pour les applications UI, le traitement des entrées utilisateur, les requêtes réseau et le travail avec les bases de données.
La bibliothèque RxKotlin
RxKotlin est une surcouche de RxJava qui ajoute des extensions pratiques pour Kotlin, telles que les lambdas, les fonctions d'extension et la prise en charge de la null-sécurité. Les types principaux :
Observable<T>— un flux qui peut émettre de 0 à N éléments et se terminer par une erreur ou avec succès.Single<T>— un flux qui émet exactement un élément ou une erreur.Flowable<T>— un flux avec prise en charge du backpressure (gestion de la vitesse de consommation).Completable— un flux qui se termine uniquement (succès/erreur) sans données.
Exemple RxKotlin
import io.reactivex.rxjava3.core.Observableimport io.reactivex.rxjava3.schedulers.Schedulers
fun main() { val observable = Observable.create<String> { emitter -> emitter.onNext("Bonjour") emitter.onNext("depuis") emitter.onNext("RxKotlin") emitter.onComplete() }
observable .subscribeOn(Schedulers.io()) .observeOn(Schedulers.single()) .subscribe( { value -> println("Reçu : $value") }, { error -> println("Erreur : ${error.message}") }, { println("Flux terminé") } )
Thread.sleep(1000) // Attente de la fin des opérations asynchrones}Dans cet exemple, un Observable est créé, qui émet trois chaînes et se termine. Les opérateurs subscribeOn et observeOn gèrent les threads d'exécution.
Coroutines et Flow en Kotlin
Depuis Kotlin 1.3, les coroutines font partie du langage, et Flow (introduit en 1.3.70) est un flux réactif entièrement intégré aux coroutines. Avantages par rapport à RxKotlin :
- Moins de frais généraux (coroutines légères vs threads Java).
- Intégration naturelle avec les fonctions suspend.
- Prise en charge de la concurrence structurée (annulation automatique à la fin du scope).
- Syntaxe plus propre sans callbacks.
Exemple Flow
import kotlinx.coroutines.*import kotlinx.coroutines.flow.*
fun main() = runBlocking { val flow = flow { for (i in 1..5) { delay(100) // Simulation d'un travail asynchrone emit(i) // Émet un élément } }
flow .map { it * it } // Transformation .catch { e -> println("Erreur : $e") } .collect { value -> println("Carré : $value") }}Flow est paresseux : les données ne commencent à être générées qu'à l'appel de collect. Les opérateurs map, filter, flatMapConcat fonctionnent de la même manière que dans Rx.
Comparaison entre RxKotlin et Flow
| Caractéristique | RxKotlin | Flow + coroutines |
|---|---|---|
| Dépendances |