In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Cold and Hot Flows
Cold Flow
- Flows created with flow builders are cold by default
Properties
Becomes active on terminal operators(like collect , first, last ....)
Becomes inactive when cancelling the collecting coroutine
They emit individual emissions to every collector
Emission and Collection are happening in same coroutines
suspend fun main(): Unit = coroutineScope {
launch {
println("Collector 1 in ${Thread.currentThread().name}")
simpleFlow().collect { value ->
println("Collecting from Collector 1 -> $value")
}
}
launch {
println("Collector 2 in ${Thread.currentThread().name}")
simpleFlow().collect { value ->
println("Collecting from Collector 2 -> $value")
}
}
}
private fun simpleFlow() = flow {
println("Emission in ${Thread.currentThread().name}")
repeat(3){
kotlinx.coroutines.delay(250)
println("Emitting $it")
emit(it)
}
}
/**
* output
* Collector 1 in DefaultDispatcher-worker-2
* Collector 2 in DefaultDispatcher-worker-1
* Emission in DefaultDispatcher-worker-2
* Emission in DefaultDispatcher-worker-1
* Emitting 0
* Emitting 0
* Collecting from Collector 1 -> 0
* Collecting from Collector 2 -> 0
* Emitting 1
* Emitting 1
* Collecting from Collector 2 -> 1
* Collecting from Collector 1 -> 1
* Emitting 2
* Emitting 2
* Collecting from Collector 2 -> 2
* Collecting from Collector 1 -> 2
*/
In above code , we can observe the following
Emissions and collectors are running in same coroutine
Individual Emissions for every collectors
Code can be found inhttps://gist.github.com/vprabhu/69d912d7dfb8751badd26dff1d8eba1a
Hot Flow
- are active regardless of existence of collectors
Properties
values that got emitted after we start collecting are the ones we will collect , it is possible to lose some emissions
stays active even when is no collectors
Emissions and collections are happening in different coroutines
Types of Hot Flow
1.Shared Flow
2.State Flow
suspend fun main(): Unit = coroutineScope {
val sharedFlow = MutableSharedFlow<Int>()
launch {
println("Emitting in ${Thread.currentThread().name}")
repeat(3) {
kotlinx.coroutines.delay(250)
println("Emitting $it")
sharedFlow.emit(it)
}
}
launch {
println("Collector 1 in ${Thread.currentThread().name}")
delay(550)
sharedFlow.collect { value ->
println("Collecting from Collector 1 -> $value")
}
}
launch {
println("Collector 2 in ${Thread.currentThread().name}")
sharedFlow.collect { value ->
println("Collecting from Collector 2 -> $value")
}
}
}
/**
* output :
* Emitting in DefaultDispatcher-worker-2
* Collector 1 in DefaultDispatcher-worker-1
* Collector 2 in DefaultDispatcher-worker-3
* Emitting 0
* Collecting from Collector 2 -> 0
* Emitting 1
* Collecting from Collector 2 -> 1
* Emitting 2
* Collecting from Collector 1 -> 2
* Collecting from Collector 2 -> 2
*
*
*/
In above code , we can observe the following
Emission and Collectors are happening in different coroutines
we can see in output where Collector 2 is the only one which collects all emissions and Collector 1 has missed emissions
Code can be found in https://gist.github.com/vprabhu/30f210ce4f9e8a3b89b2b92416e53493
In the next article , we will discuss about State Flow and Shared Flow.
Please leave your comments to improve and discuss more
Happy and Enjoy coding