How to Use SharedFlow in Kotlin: Simple Guide and Example
In Kotlin,
SharedFlow is a hot flow that lets multiple collectors receive the same emitted values. You create a MutableSharedFlow to emit values and collect them using collect in coroutines. It is useful for broadcasting events to many listeners.Syntax
SharedFlow is created using MutableSharedFlow which allows emitting values. You collect values from it using collect inside a coroutine.
MutableSharedFlow<T>(): Creates a shared flow of typeT.emit(value): Sends a value to all collectors.collect { value -> }: Receives values from the flow.
kotlin
val sharedFlow = MutableSharedFlow<Int>() // Emitting values suspend fun emitValue(value: Int) { sharedFlow.emit(value) } // Collecting values suspend fun collectValues() { sharedFlow.collect { value -> println("Received: $value") } }
Example
This example shows how to create a MutableSharedFlow, emit values from one coroutine, and collect them from another coroutine.
kotlin
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val sharedFlow = MutableSharedFlow<String>() // Collector 1 launch { sharedFlow.collect { value -> println("Collector 1 received: $value") } } // Collector 2 launch { sharedFlow.collect { value -> println("Collector 2 received: $value") } } // Emit values launch { val messages = listOf("Hello", "Kotlin", "SharedFlow") for (msg in messages) { sharedFlow.emit(msg) delay(100) // simulate work } } delay(500) // wait for all emissions }
Output
Collector 1 received: Hello
Collector 2 received: Hello
Collector 1 received: Kotlin
Collector 2 received: Kotlin
Collector 1 received: SharedFlow
Collector 2 received: SharedFlow
Common Pitfalls
One common mistake is expecting SharedFlow to replay past values by default. By default, it does not replay any value unless configured with replay. Also, emit is a suspend function and must be called from a coroutine.
Another pitfall is not launching collectors before emitting values, which causes collectors to miss emissions.
kotlin
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val sharedFlow = MutableSharedFlow<Int>() // Emitting before collecting - collectors will miss these launch { sharedFlow.emit(1) sharedFlow.emit(2) } delay(100) // delay before collector starts // Collector starts late launch { sharedFlow.collect { value -> println("Received: $value") } } delay(200) } // Correct way: start collectors before emitting fun correctUsage() = runBlocking { val sharedFlow = MutableSharedFlow<Int>() launch { sharedFlow.collect { value -> println("Received: $value") } } launch { sharedFlow.emit(1) sharedFlow.emit(2) } delay(200) }
Output
Received: 1
Received: 2
Quick Reference
- MutableSharedFlow<T>(): Create a shared flow.
- emit(value): Send value to all collectors.
- collect { }: Receive values.
- replay: Number of past values to replay to new collectors.
- extraBufferCapacity: Buffer size for emissions without suspending.
Key Takeaways
SharedFlow lets multiple coroutines receive the same emitted values simultaneously.
Always start collectors before emitting to avoid missing values.
Use MutableSharedFlow to emit values and collect to receive them.
Configure replay to send past values to new collectors if needed.
Emit is a suspend function and must be called from a coroutine.