Stylianos Gakis
03/04/2022, 8:53 PMStylianos Gakis
03/04/2022, 8:53 PMprivate val eventChannel = Channel<Event>(Channel.UNLIMITED)
val eventsFlow = eventChannel.receiveAsFlow()
What is the ācorrectā way to collect it? Right now I am doing this:
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(viewModel.eventsFlow, lifecycleOwner) {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.eventsFlow.collect { event ->
when (event) {
is Event.Foo -> doSomethingWithFooEvent(event)
}
}
}
}
Is there anything I am doing which is not necessary? key-ing the LaunchedEffect to the flow itself and the lifecycleOwner seems like itās a must, and then I am slapping a repeatOnLifecycle in there too because I am guessing I donāt want to consume the event while the App isnāt started and showing on the screen.
It certainly feels like quite a ceremony and 4 levels of indentation isnāt great either, but if this is the way to do this maybe we could make some helped functions to make this prettier.
Iāve seen a lot of discussions about this, but all the ones Iāve seen revolve around consuming a flow and converting in to State, which isnāt something I want to do here, hence the new thread š¤
Also I am aware of the new guidelines of having events as State, and consuming them and notifying the ViewModel that it was consumed, but we canāt migrate the entire code-base instantly, so weāll have to make do with this pattern too for now.Casey Brooks
03/04/2022, 9:00 PMLifecycleOwner
. The composition itself should be bound by the lifecycle, so simply collecting the flow within a normal LaunchedEffect
should scope it to the composition and ensure it's only collected during a valid lifecycle (which is when the composition itself is alive)Simon Stahl
03/04/2022, 9:05 PMval myVal = remember { vm.eventsFlow }.collectAsState(DEFAULT_VALUE).value
if you want to handle it not as state, then you can do it simply in the LaunchedEffect
LaunchedEffect(Unit) {
vm.eventsFlow.collect { do whatever with your data }
}
I don't think you need the eventsFlow
nor the lifecycleOwner
as keys, since neither of them will ever changeStylianos Gakis
03/04/2022, 9:28 PMLaunchedEffect(Unit) {
viewModel.eventsFlow.collect { event ->
when (event) {
is Event.Foo -> Timber.d(event)
}
}
}
Since when I am in the app, and I click the home button exiting the app I can see that it keeps collecting and the logs keep on coming even though I am in the home screen. This is exactly what I am avoiding by adding the repeatOnLifecycle line.Stylianos Gakis
03/04/2022, 9:41 PMCREATED
state, not in the STARTED
state.Casey Brooks
03/04/2022, 9:53 PMStylianos Gakis
03/04/2022, 11:00 PMTash
03/06/2022, 4:36 AMLifecycle
I've been using something like this from the Tivi projectStylianos Gakis
03/06/2022, 7:01 PMcollectAsState
also seems to have the same problem of collecting while the user has pressed the home button.
From what I understand this isnāt normally a problem since itās safe to update compose state while the app is in the background, but even if itās safe it may be wasting resources for no reason since it may keep alive the flows itās observing from for no reason.Tash
03/07/2022, 1:38 AMStylianos Gakis
03/07/2022, 6:14 AM