Kotlin Academy · Les

SharedFlow: eventbussen en eenmalige events

Configureer replay en extraBufferCapacity van SharedFlow voor eventdistributie.

Les 2 van 413 stappen

SharedFlow: eventbussen en eenmalige events is een gratis Kotlin Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Kotlin Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Kotlin Academy bevat in totaal 4 lessen.

Wat is SharedFlow?

SharedFlow is een warme Flow die uitzendt naar alle actieve verzamelaars. In tegenstelling tot StateFlow heeft hij geen begrip van een huidige waarde — hij is volledig gebeurtenisgestuurd.

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()
}

Parameter replay

replay buffert de laatste N uitzendingen. Nieuwe verzamelaars ontvangen onmiddellijk maximaal N eerdere gebeurtenissen. De standaardwaarde is 0 (geen herhaling).

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 voegt extra bufferruimte toe naast replay. Zenders kunnen waarden uitzenden zonder op te schorten totdat de buffer vol is.

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 voor uitzenden zonder opschorting

tryEmit(value) zendt uit zonder op te schorten en geeft false terug als de buffer vol is. Gebruik dit in contexten zonder opschorting, zoals terugroepfuncties en klikafhandelaars.

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()
}

Eenmalige gebeurtenissen (UI-navigatie)

Gebruik SharedFlow met replay=0 voor eenmalige UI-gebeurtenissen, zoals navigatie of het tonen van een Snackbar — gebeurtenissen worden niet opnieuw afgespeeld bij hercompositie.

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 tegenover StateFlow

StateFlow: toestand met huidige waarde (UI-toestand). SharedFlow: gebeurtenissen zonder persistentie (navigatie, Snackbar, analyses). Kies op basis van de vraag of gebruikers de nieuwste waarde nodig hebben.

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") }

Gebeurtenisbussysteem met SharedFlow

Implementeer een eenvoudig appbreed gebeurtenisbussysteem met een singleton-SharedFlow, als vervanging voor patronen met RxJava 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 is een StateFlow die het aantal actieve verzamelaars bijhoudt — handig om producenten stroomopwaarts te starten of te stoppen.

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() wist de gebufferde herhalingscache. Dat is handig wanneer de herhaalde gebeurtenissen verouderd zijn en nieuwe abonnees ze niet mogen zien.

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}")  // []
}

Omgaan met backpressure in SharedFlow

Gebruik bij trage verzamelaars onBufferOverflow om te kiezen tussen SUSPEND (standaard), DROP_OLDEST of 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()
}

Verzamelen met een time-out

Verzamel een SharedFlow met een time-out om een eindig aantal gebeurtenissen te verwerken en daarna te stoppen; handig voor testen of begrensde verwerking.

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")
}

Korte controle

Welke replaywaarde moet je gebruiken voor eenmalige UI-gebeurtenissen, zoals navigatie?

Samenvatting

SharedFlow is een hot-uitzender van gebeurtenissen. Gebruik replay=0 voor eenmalige gebeurtenissen en replay>0 voor late abonnees. Gebruik tryEmit in niet-suspenderende contexten. Kies SharedFlow voor gebeurtenissen en StateFlow voor toestand.

Gratis beginnen

Leer Kotlin met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
51
Lessen
203

Veelgestelde vragen

Is de les “SharedFlow: eventbussen en eenmalige events” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Kotlin Academy, waaronder “SharedFlow: eventbussen en eenmalige events”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Kotlin Academy bevat in totaal 4 lessen.

Wat leer ik in “SharedFlow: eventbussen en eenmalige events”?

Configureer replay en extraBufferCapacity van SharedFlow voor eventdistributie. Je oefent met Kotlin Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Kotlin Academy te beginnen?

Ervaring vooraf is niet nodig. Kotlin Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “SharedFlow: eventbussen en eenmalige events”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Kotlin Academy?

Ja. Elke les over Kotlin Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. StateFlow: hot statehouder voor UI
  2. SharedFlow: eventbussen en eenmalige events
  3. Cold Flow naar hot converteren met shareIn en stateIn
  4. StateFlow en SharedFlow testen met Turbine
← Terug naar Kotlin Academy