pvn
pvn

Reputation: 2126

Android Flow vs StateFlow

I recently started using Flows in Android. I read that Flows are cold StateFlows are hot, then why should we prefer using StateFlows for Android over Flows? Won't it be better to use Flows as they will stop the producer when the app goes to the background? Is there a scenario in Android development where Flows should be used over Stateflow?

Upvotes: 20

Views: 15533

Answers (4)

Ryan Chen
Ryan Chen

Reputation: 254

that actually bothers me a while before.

So I think best way to compare these two is that, StateFlow holds a value, but Flow does not. For example:

val myStateFlow = MutableStateFlow("x")
myStateFlow.value = "y" 

however, for Flow, it doesn't hold a value, instead they do something

val myFlow = flow {
   repeat(5) { emit(it) }
}

Upvotes: 10

Alex Styl
Alex Styl

Reputation: 4229

Won't it be better to use Flows as they will stop the producer when the app goes to the background?

This is not true. Flow on its own will not stop emitting when the app is in the background. In fact, the Flow interface belongs to Kotlin's coroutines and knows nothing of Android.

Simply put, a Flow will give you a new value every time a new value is emitted. A StateFlow, in addition to what a Flow is, it always holds a value. This makes them ideal for representing state (as the name suggests).

Is there a scenario in Android development where Flows should be used over Stateflow?

You can use Flow when you do not need to maintain a value and care for the emittions. An example would be a button press or user event. A StateFlow is useful for representing state (such as in your ViewModels)

Upvotes: 13

Martin Marconcini
Martin Marconcini

Reputation: 27246

The Advantage of the StateFlow over a regular Flow is that the former will stop wasting resources if the State is not the desired one.

If you look at the official StateFlow documentation you'll notice in the example the key part of this, and I quote:

// Trigger the flow and start listening for values.
// Note that this happens when lifecycle is STARTED and stops
// collecting when the lifecycle is STOPPED

This last bit is important. A Hot flow that will be collecting values so as long as the scope in which it was started is Started, and will stop when stopped. This is not what a normal Flow/Livedata would do thus wasting potential resources keeping a series of components working while, for example, the UI is stopped.

It's important to understand that LiveData and StateFlow are similar with two important distinctions (related with the above, and explained in the linked documentation):

  • StateFlow requires an initial state to be passed in to the constructor, while LiveData does not.

  • LiveData.observe() automatically unregisters the consumer when the view goes to the STOPPED state, whereas collecting from a StateFlow or any other flow does not stop collecting automatically. To achieve the same behavior, you need to collect the flow from a Lifecycle.repeatOnLifecycle block.

In other words, you could say that StateFlow is a potentially more efficient LiveData that gives you the ability to say: If the state is XYZ, then stop collecting and using resources because I have my reasons (e.g.: my UI is gone, so i don't need to listen to stuff I cannot process).

Upvotes: 21

Enes Zor
Enes Zor

Reputation: 1220

Firstly, I would like to mention that StateFlow is already implemented Flow interface if you check implementation of source code. StateFlow is observable data holder which gives always last value of pipeline. It makes sense to compare it with LiveData actually. You already right that it is hot unlike flow is cold. If you want to stop producer when the app goes the background, Channel API is better for this purpose. If we come what is the Flow purpose, you can handle multiple suspend methods via Flow API. For example : You can observe two suspend function continuously.

Upvotes: 1

Related Questions