I'd like to ask you about using "hot" Flow
streams in the android app.
Let's start with simple, example scenario. We have an app, with Room
database, MVVM
architecture pattern, and Flow
with Coroutines
for manipulating data from database.
There are a couple of fragments inside the app. Every fragment have it's own ViewModel
, but they have one thing in common - all of them have same, two things from database:
I'd like to ask, if it is a good way to modify Flow
from "cold" stream, to "hot", by using .stateIn
. Since all of fragments
have recalls to the List
and String
that I've meantioned above.
Does implementing the hot stream with LifeCycle.State.STARTED
would be more efficient, than implementing the cold stream? I'm just trying to figure out, which stream
should I choose according to the situation.
Really, you almost always want to use a hot Flow on Android if you're not using Compose, because even if data is only used by one Fragment, that Fragment might get recreated during a screen rotation, and it would waste resources to restart the flow from scratch to fetch the same data every time the screen rotates.
(If you're using Compose, you likely want to disable screen rotation configuration changes in the manifest. But you still might like to use a hot flow for cases like when a user accidentally taps something to go to another screen and then backs up to the original fragment quickly.)
Does implementing the hot stream with LifeCycle.State.STARTED would be more efficient, than implementing the cold stream?
I don't know what you mean by implementing a hot stream with a Lifecycle state.
The common pattern for creating a hot Flow on Android is to use SharingStarted.WhileSubscribed(5000L)
. This allows the Flow to remain idle when not in use, but avoids restarting it during a screen rotation (which is assumed to take less than 5 seconds). You can probably reduce this number, but I think it's the same window of time Jetpack's LiveData uses.
Since you have separate ViewModels, but both Fragments want to use the same data, I think it makes sense to use shareIn
or stateIn
for a property in the shared repository class. This is probably breaking some MVVM "rule" since it's making your repository slightly aware of how your UI is designed. Up to you. The alternative I guess is to do it in a third ViewModel that is used by both of your Fragments.