Coroutines Flow - 1
Coroutines Flow - 1
803 1
What comes to mind when you hear the word “flow”? It may occur to you as
something continuous, such as a stream.
What is Flow?
A stream of data that can be computed asynchronously is conceptually
referred to as a Flow.
To collect flow, first you will launch a Coroutine because flow operates on
Coroutines under the hood. The collect operator is used to collect the values
emitted by it.
lifecycleScope.launch {
viewModel.numbersFlow.collect { it ->
binding.textTimer.text = it.toString()
}
}
Types of Flow
Cold Flow — It does not start producing values until one starts to collect
them. It can have only one subscriber.
e.g. flow
Hot Flow — It will produce values even if no one is collecting them.
e.g. StateFlow, SharedFlow
Intermediate Operators — These are map, filter, take, zip, etc. They only
set up a chain of operations for future execution and quickly return.
Filter Operator
Returns a flow containing only values of the original flow that match the
given predicate.
Map Operator
Returns a flow containing the results of applying the given transform
function to each value of the original flow.
withIndex Operator
Returns a flow that wraps each element into IndexedValue, containing value
and its index (starting from zero).
lifecycleScope.launch {
viewModel.numbersFlow.map { it ->
it * it
}.filter { it ->
it % 2 == 0
}.catch { exception ->
handleException(exception)
}.collect { it ->
binding.tvFlow.text = it.toString()
}
}
StateFlow:
It is a hot flow. Its active instance exists independently of the presence of
collectors.
It does not emit consecutive repeated values. When the value differs from
the previous item, it emits the value.
class CounterModel {
private val counter = MutableStateFlow(0) // private mutable state flow
val counterValue = counter.asStateFlow() // public read-only state flow
fun incrementAtomically() {
counter.update { count -> { count + 1 }
}
fun incrementCounter() {
val count = counter.value
counterValue.value = count + 1
}
}
SharedFlow:
By default, it does not emit any value since it does not need an initial
value.
The emitter emits all the values without caring about the distinct
differences from the previous item. It emits consecutive repeated values
also.
class EventBus {
private val events = MutableSharedFlow<Event>() // private mutable shared fl
val eventsValue = events.asSharedFlow() // public read-only shared flow
callbackFlow
callbackFlow is a flow builder that lets you convert callback-based API into
flows.
The resulting flow is cold, which means that [block] is called every time a
terminal operator is applied to the resulting flow.
Room, DataStore, Paging3 and other various libraries provide support for
Flow.
Flow is extremely appropriate for data updates. For example, you can use
flow with Room to be notified of changes in your database.
Summary
In conclusion, Kotlin Flow is a reactive programming library for Kotlin that
provides a way to asynchronously process streams of data. Its concise and
streamlined syntax, based on Coroutines, makes it easy to create and
manipulate data streams.
In addition, Kotlin offers StateFlow and SharedFlow, which are useful for
managing and sharing state across different parts of an application.
StateFlow is ideal for managing stateful data, while SharedFlow can buffer
and emit values to new subscribers when they first subscribe.
Overall, Kotlin Flow, StateFlow, and SharedFlow are powerful and flexible
tools for managing and processing streams of data in Kotlin, and they are
rapidly gaining popularity among developers as essential components of
modern reactive programming.
Happy Coding!
Please don’t forget to give claps 👏 and share this with your fellow coder
friends.
For more such insights and updates on the latest tools and technologies — follow
the Simform engineering blog.