0Pricing
Kotlin Academy · Leçon

SharedFlow : bus d’événements et événements ponctuels

Configurez la relecture de SharedFlow et extraBufferCapacity pour diffuser des événements.

SharedFlow : bus d’événements et événements ponctuels est une leçon Kotlin Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Kotlin Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Kotlin Academy comprend 4 leçons au total.

Qu'est-ce que SharedFlow ?

SharedFlow est un flux chaud qui diffuse les valeurs à tous les collecteurs actifs. Contrairement à StateFlow, il ne possède pas de valeur actuelle : il est exclusivement fondé sur les événements.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val events = MutableSharedFlow<String>()
    launch { events.collect { println("Collector 1: $it") } }
    launch { events.collect { println("Collector 2: $it") } }
    delay(50)
    events.emit("UserLoggedIn")
    events.emit("DataRefreshed")
    delay(50)
    coroutineContext.cancelChildren()
}

Paramètre replay

replay met en mémoire tampon les N dernières émissions. Les nouveaux collecteurs reçoivent immédiatement jusqu'à N événements passés. La valeur par défaut est 0 (aucun rejeu).

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>(replay = 2)
    flow.emit(1); flow.emit(2); flow.emit(3)
    // Late subscriber gets last 2:
    flow.collect { print("$it ") }  // prints 2 3
}

extraBufferCapacity

extraBufferCapacity ajoute de l'espace tampon au-delà du rejeu. Les émetteurs peuvent émettre sans être suspendus jusqu'à ce que le tampon soit plein.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>(
        replay = 0,
        extraBufferCapacity = 10
    )
    // Can emit up to 10 times without a collector ready:
    repeat(10) { flow.tryEmit(it) }
    launch { flow.collect { print("$it ") } }
    delay(50)
    coroutineContext.cancelChildren()
}

tryEmit pour émettre sans suspension

tryEmit(value) émet sans suspendre l'exécution et renvoie false si le tampon est plein. Utilisez-le dans les contextes qui ne peuvent pas être suspendus (rappels, gestionnaires de clics).

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<String>(extraBufferCapacity = 5)
    val ok = flow.tryEmit("click")  // non-suspending
    println("Emitted: $ok")
    launch { flow.collect { println(it) } }
    delay(50)
    coroutineContext.cancelChildren()
}

Événements ponctuels (navigation de l'interface utilisateur)

Utilisez SharedFlow avec replay=0 pour les événements ponctuels de l'interface utilisateur, comme la navigation ou l'affichage d'une barre de notification : les événements ne sont pas rejoués lors de la recomposition.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
class NavViewModel {
    private val _events = MutableSharedFlow<String>()
    val events = _events.asSharedFlow()
    fun navigateTo(route: String) {
        // viewModelScope.launch:
        kotlinx.coroutines.GlobalScope.launch { _events.emit(route) }
    }
}
// Collect in UI:
// viewModel.events.collect { route -> navController.navigate(route) }

SharedFlow et StateFlow

StateFlow : état avec une valeur actuelle (état de l'interface utilisateur). SharedFlow : événements sans persistance (navigation, barre de notification, analyses). Choisissez selon que les consommateurs ont besoin ou non de la dernière valeur.

import kotlinx.coroutines.flow.*
// StateFlow: always has a value; new subscribers get current value
val uiState = MutableStateFlow("idle")

// SharedFlow: no stored value; events fire and are gone (unless replay>0)
val singleEvents = MutableSharedFlow<String>(replay = 0)

fun main() { println("State = what it is; Event = what happened") }

Bus d'événements avec SharedFlow

Implémentez un bus d'événements simple à l'échelle de l'application à l'aide d'un SharedFlow singleton, en remplacement des modèles fondés sur RxJava et PublishSubject.

import kotlinx.coroutines.flow.*
object EventBus {
    private val _events = MutableSharedFlow<Any>(extraBufferCapacity = 100)
    val events = _events.asSharedFlow()
    fun post(event: Any) { _events.tryEmit(event) }
}
sealed class AppEvent {
    object UserLoggedOut : AppEvent()
    data class ShowError(val msg: String) : AppEvent()
}
// Usage: EventBus.post(AppEvent.UserLoggedOut)

subscriptionCount

sharedFlow.subscriptionCount est un StateFlow qui suit le nombre de collecteurs actifs. Il est utile pour démarrer ou arrêter les producteurs en amont.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>()
    println("Subscribers: ${flow.subscriptionCount.value}")  // 0
    val job = launch { flow.collect { } }
    delay(50)
    println("Subscribers: ${flow.subscriptionCount.value}")  // 1
    job.cancel()
    delay(50)
    println("Subscribers: ${flow.subscriptionCount.value}")  // 0
}

resetReplayCache

resetReplayCache() efface le cache de rejeu mis en mémoire tampon. C'est utile lorsque les événements rejoués sont obsolètes et que les nouveaux abonnés ne doivent pas les voir.

import kotlinx.coroutines.flow.*
fun main() {
    val flow = MutableSharedFlow<Int>(replay = 3)
    flow.tryEmit(1); flow.tryEmit(2); flow.tryEmit(3)
    println("Replay cache: ${flow.replayCache}")  // [1, 2, 3]
    flow.resetReplayCache()
    println("Replay cache: ${flow.replayCache}")  // []
}

Gestion de la contre-pression dans SharedFlow

Lorsque les collecteurs sont lents, utilisez onBufferOverflow pour choisir entre SUSPEND (valeur par défaut), DROP_OLDEST ou DROP_LATEST.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.channels.BufferOverflow
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>(
        replay = 0,
        extraBufferCapacity = 3,
        onBufferOverflow = BufferOverflow.DROP_OLDEST
    )
    repeat(10) { flow.tryEmit(it) }
    launch {
        flow.collect { println(it) }  // only sees most recent 3
    }
    delay(50)
    coroutineContext.cancelChildren()
}

Collecte avec délai d’expiration

Collectez un SharedFlow avec un délai d’expiration pour traiter un nombre fini d’événements, puis arrêter la collecte, ce qui est utile pour les tests ou le traitement limité.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val events = MutableSharedFlow<String>()
    launch { repeat(5) { delay(50); events.emit("Event $it") } }
    withTimeoutOrNull(200) {
        events.collect { println(it) }
    }
    println("Done collecting")
}

Vérification rapide

Quelle valeur de relecture devez-vous utiliser pour des événements d’interface à usage unique, comme la navigation ?

Récapitulatif

SharedFlow est un diffuseur d’événements chaud. Utilisez replay=0 pour les événements à usage unique et replay>0 pour les abonnés tardifs. Utilisez tryEmit dans les contextes qui ne permettent pas la suspension. Choisissez SharedFlow pour les événements et StateFlow pour l’état.

Questions Fréquemment Posées

La leçon « SharedFlow : bus d’événements et événements ponctuels » est-elle gratuite ?

Oui — le texte complet de « SharedFlow : bus d’événements et événements ponctuels » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Kotlin Academy, passe à CoddyKit PRO. Le cours Kotlin Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « SharedFlow : bus d’événements et événements ponctuels » ?

Configurez la relecture de SharedFlow et extraBufferCapacity pour diffuser des événements. Tu pratiques Kotlin Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Kotlin Academy ?

Aucune expérience préalable n'est requise. Kotlin Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « SharedFlow : bus d’événements et événements ponctuels » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Kotlin Academy ?

Oui. Chaque leçon Kotlin Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. StateFlow : conteneur d’état actif pour l’interface utilisateur
  2. SharedFlow : bus d’événements et événements ponctuels
  3. Transformer un Flow froid en flux actif avec shareIn et stateIn
  4. Tester StateFlow et SharedFlow avec Turbine
← Retour à Kotlin Academy