Saturday, October 5, 2024

StateFlow and SharedFlow seem similar, but they are designed for different use cases

 



StateFlow and SharedFlow seem similar, but they are designed for different use cases, and they should not be confused. Let's discuss the key differences and usages.


Let's start with how they work. SharedFlow resembles a broadcast channel—emitted values are delivered to all observers. It allows setting a replay parameter specifying how many past values should be emitted to new observers.

StateFlow behaves a lot like SharedFlow with reply = 1, but StateFlow must always have a value, so an initial value must be specified when a StateFlow is created. This value can be accessed or changed using value property.

But StateFlow was designed for a concrete use case: to represent an observable state. In Android, it is used to represent the state of our application, and views observe it and redraw whenever it changes. That is the key source of differences.

Redrawing view can be expensive, and state changes can be frequent. That is why two optimizations were introduced. First, updates are only emitted when they are different from the previous state. This behavior can be achieved on SharedFlow using distinctUntilChanged.

Second, StateFlow is conflated, meaning if observer is slower than value changes, it might lose some intermediate updates. That is appropriate for StateFlow, because we are not interested in drawing obsolete state.

StateFlow also have some tools for state update, like update function, that lets us safely update state, by creating a new one based on the current one.

That is why StateFlow should be used concretely to represent the observable state of our application. It should not be used as a "breadcast channel". For that we use SharedFlow.

Let's see an Android example: Things like a progress bar or data to display should be represented by StateFlow, but exceptions or messages to show to users as toasts should be represented as SharedFlow.

However, SharedFlow values are not completely safe to be used in view models, because updates made when there is no observer will not be observed (unless we use reply, but then the same values can be displayed again). So it is best to represent our state with StateFlow.

Now let's see a backend example. On a backend service, updates received from some websocket should be represented using SharedFlow, but an observable counter of application users can be represented using StateFlow.

To sum up, StateFlow and SharedFlow are similar, but they are designed for different use cases. StateFlow is for representing observable state, and SharedFlow is for broadcasting events. Use them accordingly.
Credits 
https://www.linkedin.com/posts/marcin-moskala_stateflow-and-sharedflow-seem-similar-but-activity-7244273218692202496-yej-?utm_source=share&utm_medium=member_desktop

No comments :

Post a Comment