Use StateFlow in Android

Tram Ho


StateFlow is described as a flow that represents a read-only state with a single updatable data value that generates value updates to its flow collectors. StateFlow is a useful data-model to represent any kind of state, it is designed to be used in situations where state management is required in asynchronous execution with Kotlin Coroutines. StateFlow is raised to stable API since Kotlin Coroutines 1.4.0 version Kotlin Coroutines 1.4.0

StateFlow comes in two variations: StateFlow and MutableStateFlow :

  • StateFlow<T> interface provides only value access.
  • MutabaleStateFlow<T> interface provides the ability to modify values.

StateFlow ‘s StateFlow is denoted by value through the value property. The value property always has an initial value so it can be safely read at any time. Any updates to the value will be reflected in all receivers by emitting a value with status updates. In Android, StateFlow great for classes that need to maintain an observable state of change.

A simple example of how to use State flow:

This snippet is quite similar to the usage of LiveData :

  • Declare _countState as MutableStateFlow to initialize value and provide ability to update value.
  • Declare an instance of StateFlow as the countState exposed to the Views ( read-only field ).

When the receiver begins to collect values ​​from StateFlow , the receiver gets the last state in the stream and any subsequent states. The values ​​in StateFlow are combined using the Any.equals comparison in a similar way to the distinctUntilChanged operator. It is used to incorporate value updates in a MutableStateFlow and to prevent outputting values ​​to the receiver when the new value is equal to the previously emitted value.

Example views that listen to StateFlow :

The example uses viewLifecycleOwner.lifecycleScope.launchWhenStarted to bind to the lifecycle of the views.

StateFlow and LiveData

StateFlow and LiveData have similarities. Both are classes of observable data, and both follow a similar pattern when used in application architecture. However, StateFlow and LiveData have different behaviors:

  • StateFlow requires an initial state passed into the constructor while LiveData does not.
  • StateFlow prevents StateFlow of values ​​to a receiver when a new value is equal to a previously issued value.
  • LiveData.observe() automatically unsubscribes consumers when the UI switches to STOPPED , while collect from a StateFlow or any other stream does not.

In addition, StateFlow can use many good operators of Flow (zip, combine …) while LiveData very limited.

In the example above using viewLifecycleOwner.lifecycleScope.launchWhenStarted to realize the lifecycle when collecting from flow, to avoid wasting resources. Alternatively, handling when changing the Lifecycle states manually is also possible, as shown in the following example:

Another way to stop listening for uiState changes when the UI isn’t showing is to use the asLiveData() function in the lifecycle-livedata-ktx library to convert the flow back to LiveData😃:


Share the news now

Source : Viblo