An Interest In:
Web News this Week
- April 2, 2024
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
- March 28, 2024
- March 27, 2024
Introduction to Kotlin Flows and Channels
Summarizing the behaviors of using Kotlin flows (cold stream) and Kotlin channels (hot stream)
This is part of the asynchronous flow series:
- Part 1 - Exploring Android LiveData Usages and Behaviors
- Part 2 - Introduction to Kotlin Flows and Channels
Kotlin Flow
is cold stream, Kotlin Channel
is hot stream. The differences between hot and cold streams are summarized below.
Cold Stream vs Hot Stream
Behaviors | Cold Stream | Hot Stream |
---|---|---|
Where data is produced? | Inside the stream | outside the stream |
Unicast or multicast? | Unicast | Multicast |
Lazy or eager stream? | Lazy stream | Eager stream |
Terminology
- Unicast - has only one subscriber per stream, new subscription creates new stream
- Multicast - has no or many subscribers per stream, new subscription uses existing stream
- Lazy stream - start emitting values only when someone start subscribing to it
- Eager stream - start emitting values even it does NOT have any subscribers
Kotlin Flows
Flow
data is produced inside the stream by creating the Flow
and calling the FlowCollector<T>.emit()
. It is called upstream flow.
val flow: Flow<Int> = flow { repeat(10000) { value -> delay(1000) emit(value) }}
However, the data won't be emitted until the Flow<T>.collect()
is called. This is an example of collecting flow in ViewModel
. It is called downstream flow.
viewModelScope.launch { flow.collect { value -> /* collecting $value here */ } }
Each time the Flow<T>collect()
is called, a new cold stream is created. It is called unicast. Data is only emitting at this point - lazy stream.
Kotlin Channels
Channel
data is produced outside the stream. Creating the channel and sending the data into the hot stream are separated. Sending data to the hot stream is called channel's sender.
Create the Channel
private val channel = Channel<Int>()
Send Data into the Hot Stream
viewModelScope.launch { repeat(10000) { value -> delay(1000) channel.send(value) }}
Hot stream is like a buffer which has the buffer capacity. The default buffer capacity is zero. By default, when the buffer is overflow, the data sending is suspended until there is a receiver.
To receive the channel's data, you call the Channel.receive()
. This is called the channel's receiver.
viewModelScope.launch { while(true) { val value = channel.receive() }}
Since the buffer capacity is zero by default, the buffer overflow happens as soon as you're sending the first data into the stream. Thus, the data sending is suspended after the first data until there is a receiver. This behavior looks very similar to lazy stream, but it is NOT. It is still an eager stream.
Imagine if the buffer capacity is more than zero, sending data occurs even without any receiver until the buffer is full. Thus, it is an eager stream.
Unlike Flow
, having a new subcriber or new channel's receiver does not create a new stream. It still uses the existing stream. Thus, it is multicast stream.
One thing I would like to emphasize is once the data is received, the data is removed from the hot stream / buffer.
Based on the diagram above, assuming there are already channel's receiver #1, #2 and #3 subscribing to the channel (calling the Channel.receive()
function), the channel's sender is sending 1
, 2
and 3
to the hot stream.
- Once
1
is received by receiver #1, receiver #2 and #3 won't receive1
anymore. - Receiver #2 receives
2
instead, and receiver #3 receives3
.
Conclusion
I just summarize the behavior of using Flow
and Channel
at high-level. I do not really know any practical usages of them, especially Channel
.
These are the notes that I have written down:
Flow
- store single value that changes over timeChannel
- store one-time event, collected by one observer?
Flow
probably makes sense. I have been using it to expose the data from a local database. But honestly, when do we use Channel
? Snackbar? If you have a good practical usage of it, please share that with me.
[Updated - Sept 23, 2022]: After doing some researches and found the following article by Google team which basically does NOT recommend
Channel
for one-time event. In short, use everything withStateFlow
- will be covered in next article.
Source Code
GitHub Repository: Demo_AsyncFlow (see FlowActivity
and ChannelActivity
)
Originally published at https://vtsen.hashnode.dev.
Original Link: https://dev.to/vtsen/introduction-to-kotlin-flows-and-channels-12o9
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To