That is a part of the asynchronous movement sequence:
Kotlin Circulate
is a chilly stream, Kotlin Channel
is a sizzling stream. The variations between cold and warm streams are summarized beneath.
Chilly Stream vs Sizzling Stream
Behaviors | Chilly Stream | Sizzling Stream |
The place information is produced? | Contained in the stream | outdoors the stream |
Unicast or multicast? | Unicast | Multicast |
Lazy or keen stream? | Lazy stream | Keen stream |
Terminology
-
Unicast – has just one subscriber per stream, new subscription creates new stream
-
Multicast – has no or many subscribers per stream, new subscription makes use of present stream
-
Lazy stream – begin emitting values solely when somebody begin subscribing to it
-
Keen stream – begin emitting values even it does NOT have any subscribers
Kotlin Flows
Circulate
information is produced contained in the stream by creating the Circulate
and calling the FlowCollector<T>.emit()
. It’s referred to as upstream movement.
val movement: Circulate<Int> = movement {
repeat(10000) { worth ->
delay(1000)
emit(worth)
}
}
Nevertheless, the information will not be emitted till the Circulate<T>.gather()
is known as. That is an instance of gathering movement in ViewModel
. It’s referred to as downstream movement.
viewModelScope.launch {
movement.gather { worth ->
}
}
Every time the Circulate<T>gather()
is known as, a brand new chilly stream is created. It’s referred to as unicast. Knowledge is barely emitting at this level – lazy stream.
Kotlin Channels
Channel
information is produced outdoors the stream. Creating the channel and sending the information into the recent stream are separated. Sending information to the recent stream is known as channel’s sender.
Create the Channel
personal val channel = Channel<Int>()
Ship Knowledge into the Sizzling Stream
viewModelScope.launch {
repeat(10000) { worth ->
delay(1000)
channel.ship(worth)
}
}
Sizzling stream is sort of a buffer, which has the buffer capability. The default buffer capability is zero. By default, when the buffer is overflow, the information sending is suspended till there’s a receiver.
To obtain the channel’s information, you name the Channel.obtain()
. That is referred to as the channel’s receiver.
viewModelScope.launch {
whereas(true) {
val worth = channel.obtain()
}
}
-
For the reason that buffer capability is zero by default, the buffer overflow occurs as quickly as you are sending the primary information into the stream. Thus, the information sending is suspended after the primary information till there’s a receiver. This habits appears to be like similar to lazy stream, however it’s NOT. It’s nonetheless an keen stream.
-
Think about if the buffer capability is greater than zero, sending information happens even with none receiver till the buffer is full. Thus, it’s an keen stream.
Not like Circulate
, having a brand new subscriber or new channel’s receiver doesn’t create a brand new stream. It nonetheless makes use of the present stream. Thus, it’s multicast stream.
One factor I want to emphasize is as soon as the information is acquired, the information is faraway from the recent stream / buffer.
Primarily based on the diagram above, assuming there are already channel’s receiver #1, #2 and #3 subscribing to the channel (calling the Channel.obtain()
operate), the channel’s sender is sending 1
, 2
and 3
to the recent stream.
-
As soon as
1
is acquired by receiver #1, receiver #2 and #3 will not obtain1
anymore. -
Receiver #2 receives
2
as an alternative, and receiver #3 receives3
.
Conclusion
I simply summarize the habits of utilizing Circulate
and Channel
at high-level. I do probably not know any sensible usages of them, particularly Channel
.
These are the notes that I’ve written down:
-
Circulate
– retailer single worth that adjustments over time -
Channel
– retailer one-time occasion, collected by one observer?
Circulate
most likely is sensible. I’ve been utilizing it to show the information from a neighborhood database. However truthfully, when can we use Channel
? Snackbar? When you have sensible use of it, please share that with me.
[Updated – Sept 23, 2022]: After doing a little analysis and located the next article by Google crew which does NOT advocate
Channel
for a one-time occasion. In brief, use the whole lot withStateFlow
– can be coated within the subsequent article.
Supply Code
GitHub Repository: Demo_AsyncFlow (see FlowActivity
and ChannelActivity
)