Hot vs cold flows — Kotlin Coroutines
Shubham Sharma
Immediate Joiner (Kotlin | MVVM | Jetpack Compose | Flutter | React Native??)
In Kotlin, a hot flow is a type of flow that continuously emits values, even when there are no active collectors, such as with a SharedFlow or StateFlow.
On the other hand, a cold flow only starts producing and emitting values when at least one collector is actively collecting, as seen with a regular Flow.
But what does that actually mean?
Let’s dive into an example comparing a cold Flow with a hot SharedFlow to better understand the distinction.
Cold Flow Example
A cold flow only emits values when a collector is actively collecting. Each collector triggers a fresh emission sequence.
val coldFlow = flow {
println("Emitting values...")
emit(0)
emit(1)
}
launch {
println("Starting cold flow collection...")
coldFlow.collect { value ->
println("Cold flow collector received: $value")
}
}
// Result
Emitting values...
Starting cold flow collection...
Cold flow collector received: 0
Cold flow collector received: 1
At the start, no emissions occur because there are no active collectors. Only when a collector subscribes does the flow start emitting values, triggering emit(0) and emit(1). This behavior is why it's said that cold flows "emit values only when there is an active collector."
Each new collector will restart the flow, receiving the same sequence of values [0, 1], as the emissions are re-triggered for every subscriber.
SharedFlow Example
A hot flow like SharedFlow emits values immediately, even if no collector is actively collecting at the time. Collectors receive values emitted after they start collecting.
val sharedFlow = MutableSharedFlow<Int>()
// Emitting a value before any collector starts
sharedFlow.emit(0)
launch {
println("Starting SharedFlow collection...")
sharedFlow.collect { value ->
println("SharedFlow collector received: $value")
}
}
// Emitting values after the collector starts
sharedFlow.emit(1)
sharedFlow.emit(2)
// Result
Starting SharedFlow collection...
SharedFlow collector received: 1
SharedFlow collector received: 2
Initially, it emits 0 immediately, but without any collectors, this value is essentially "missed." When a collector subscribes, it does not receive the earlier emissions because it was registered after the emission of 0.
Instead, the collector will pick up any subsequent emissions, such as [1, 2], resulting in those values being received.
领英推荐
StateFlow Example (Hot Flow with a Current State)
val stateFlow = MutableStateFlow(0) // Holds a default initial value
// Collector 1
launch {
stateFlow.collect { value ->
println("StateFlow Collector 1 received: $value")
}
}
// Update stateFlow's value
stateFlow.value = 1
stateFlow.value = 2
// Collector 2 (starts collecting from the latest value)
launch {
stateFlow.collect { value ->
println("StateFlow Collector 2 received: $value")
}
}
// Result
StateFlow Collector 1 received: 0
StateFlow Collector 1 received: 1
StateFlow Collector 1 received: 2
StateFlow Collector 2 received: 2
StateFlow always holds a current value and emits it immediately to any new collectors. In this example, Collector 2 receives the latest value (2) when it starts collecting, while Collector 1 gets all updates starting from the initial value.
To help you remember the difference:
Regular Flow
SharedFlow
StateFlow
Proficient in C++ and Kotlin | Android Developer Specializing in Creating High-Performance, User-Centric Applications | Kotlin | MVVM | Retrofit | DaggerHilt
3 个月Very informative