Erik
11/03/2020, 7:03 PMSingleLiveEvent
(Android pattern when using view models and live data) be modeled using flows?
I think that the documentation of fun <T> ReceiveChannel<T>.receiveAsFlow(): Flow<T>
(https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/receive-as-flow.html) describes this specific use case:
Represents the given receive channel as a hot flow and receives from the channel in fan-out fashion every time this flow is collected. One element will be emitted to one collector only.So, if I just create a
private val _events = Channel<MyEvent>()
in my ViewModel
and expose it as val events = _events.receiveAsFlow()
, would that behave like a single live event? I.e.: one collector only receives the event, all others don't? Or are there additional things to consider? I'm a bit confused about the existence of (Mutable)SharedFlow
(and the now obsolete BroadcastChannel
), but I think this will always share emissions between all active collectors (subscribers) and that's precisely what single live event tries to prevent, am I right?Adam Powell
11/03/2020, 7:06 PMChannel.receiveAsFlow
is a good replacement. SingleLiveEvent
is an antipattern with a lot of workarounds and kludges to try to make LiveData behave closer to something like a Flow or Channel.Adam Powell
11/03/2020, 7:08 PMChannel.receiveAsFlow
will allow multiple collectors but each value sent to the channel will only be received by a single collector.Erik
11/03/2020, 7:14 PMAgreed. Still, the use case is very clear and (albeit specific) not really readily supported in the Kotlin coroutines API. At this time it seems that using ais an antipatternSingleLiveEvent
SendChannel
as entrance and ReceiveChannel.asFlow()
as exit is the shortest path between a single event generator and a flow consumers. The good news is that Channel
is both a SendChannel
and a ReceiveChannel
.Erik
11/03/2020, 7:14 PMgildor
11/04/2020, 12:01 AMCircusmagnus
11/04/2020, 6:28 AMCircusmagnus
11/04/2020, 6:35 AMAdam Powell
11/04/2020, 6:41 AMgildor
11/04/2020, 6:47 AMErik
11/04/2020, 7:06 AMErik
11/04/2020, 7:08 AMCircusmagnus
11/04/2020, 7:09 AMgildor
11/04/2020, 7:22 AMPerformance wise idk if using a channel received as a flow, or just a state flow with a consumable layer is more taxing on CPU/memoryChannel is a lot slower than simple StateFlow, it creates multiple objects on every emit (mostly because it’s thread safe) Anyway, neither consumable wrapper for even, nor even expensive channel emissions probably not a problem at all except cases when you have events every few milliseconds