so when I use StateFlow, the consumer dont unregis...
# coroutines
v
so when I use StateFlow, the consumer dont unregister when view is in STOPPED state, then this will consume more resources or something then why should we use stateflow instead of livedata? I cant understand the use of stateflow and below is snippet written in docs
j
lifeCycleScope
and
viewModelScope
will take take of unregistering when necessary for you : https://developer.android.com/topic/libraries/architecture/coroutines#lifecycle-aware
o
@jean not exactly. Instead of unregistering, it just suspends, so the producer is still active https://developer.android.com/kotlin/flow/stateflow-and-sharedflow:
Note: Using 
launchWhen()
 functions from the Lifecycle Kotlin extensions to collect a flow from the UI layer is not always safe. When the view goes to the background, the coroutine suspends, leaving the underlying producer active and potentially emitting values that the view doesn't consume. This behavior could waste CPU and memory resources.
*`StateFlow`*s are safe to collect using the 
launchWhen()
 functions since they're scoped to *`ViewModel`*s, making them remain in memory when the 
View
 goes to the background, and they do lightweight work by just notifying the 
View
 about UI states. However, the problem might come with other producers that do more intensive work.
A way to combat this is always have a backed shared flow that collects while subscribed.
👍 2
j
thanks for pointing this out to me 🙂 what do you mean by having a backed shared flow?
o
Instead of
Copy code
val users: Flow<List<User>> = observeUsers()
its
Copy code
val users: Flow<List<User>> = observeUsers()
    .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
v
@jean yeah lifecyclescope and vmscope, takes care of coroutines lifecycle defined in that scope, not of the consumer/observer of Stateflow, and thanks @Orhan Tozan
But I was asking like what is adv of stateflow over livedata
o
What the advantage of stateflow over livedata is, is that you have access to the Flow API, plus it's Android agnostic (Kotlin multiplatform). I think when your project is already using coroutines, you should reverse the question and ask yourself: what is the advantage of livedata over stateflow?
v
yeah, livedata is android framework-specific, flow API is not, this is a huge adv in things like KMM thanks, yeah I should ask what is adv of livedata over Stateflow 😅
j
just to be aware that there are some subtleties still if using in Compose project https://johnoreilly.dev/posts/jetpack-compose-stateflow-livedata/
(though just to mention I haven't confirmed behaviour in recent compose updates.....I think this is something they were hoping to address...or at least provide mechanism whereby this behaviour could be adjusted)
j
is it possible to set a
SharingStarted
property on a state/shared flow declared like this
val state = Mutable[State/Shared]Flow(initialValue)
? I see the doc says
the problem might come with other producers that do more intensive work
what is intensive enough and does it mean it should be changed to a backed shared flow instead?
v
@John O'Reilly thank you for sharing, will try things in new compose updates
o
@jean what is intensive enough is up to you to decide. What the point essentially comes down to, is that, say you have a screen that is collecting a flow that fetches data every 5 seconds. Now let's say you navigate away from the app. The UI won't be notified anymore about the new flow emits, but the flow is still running and fetching every 5 seconds, despite the user isn't even on the screen
Since the lifescycle scope doesn't actually get canceled, it still is alive
j
yes I get that point 🙂 I’m just curious to know what would justify the change from one to the other.