(StateFlow & ShareFlow) VS (Flow & LiveData)

Table of Contents

data flow

General process

Switch thread

StateFlow & ShareFlow

StateFlow

Build StateFlow &ShareFlow


In the previous articles on Flow, collect function analysis and imitation of Flow builder to create data flow articles, we explored the simple use of flow and its simple principles. However, during the production process, we often borrow these basic APIs to implement our complex logic processing. , two special flows, StateFlow and SharedFlow, have also been launched based on demand. Next, let’s take a look at the special features and application scenarios of these Flows~~

Officially recommended Flow data flow direction:

data process

The data flow contains three entities:

  • Providers generate data that is added to the data flow. Thanks to coroutines, data streams can also generate data asynchronously.
  • (Optional) Mediators can modify the values sent to the data flow, or modify the data flow itself.
  • Consumers use the values from the data stream.

Entities included in the data flow; consumers, optional intermediaries, and providers

About process

  • Producer is provided through the Model layer of MVVM, and the DataLayer layer of DDU provides the original data stream;
  • Intermediary provides operations for converting data streams that can be directly used for display through the ViewModel layer of MVVM and the DomainLayer layer of DDU.
  • Consumer uses the converted data stream to render and display data through the View layer of MVVM and the UI layer of DDU.

I won’t introduce the basic use of flow. Readers can check out the two links provided at the beginning.

Switch thread

It is not allowed to use different ConretineContext to emit and submit data inside the flow, so if you want to switch threads internally, you can use the flowOn operator to convert it.

StateFlow & amp; ShareFlow

StateFlow and SharedFlow are Flow APIs that allow data flows to optimally emit state updates and emit values to multiple consumers.

These two Flows are different from ordinary Flows. As we know about Flow, the function passed in by flow will be executed only when collect is called. Every time collect is called, the flow will be walked through again. Function(essentially an extension function), this extension function is executed when collect is called; but these two Flows are different. They do not depend on external calls (can be configured and explained later). They are hot flows, and the data they send out It will be cached and notified to subscribers when there are subscribers.

StateFlow and SharedFlow emits state update and emits values to multiple consumers and can obtain the current value through the value attribute Latest value. Similar to observing data, data is updated, and the user accepts the latest data. Is it very similar to LiveData? It’s true, but it’s more powerful than LiveData~~

StateFlow
  • Thread switching: Compared with LiveData, the operation of updating data can only be performed on the main thread, but Flow can run on different Dispatchers (a type of thread dispatcher, CoruntineContext) through flowOn to switch threads. More convenient to operate
  • Data backtracking: Compared to LiveData, which automatically manages the version to decide whether to notify Ovserve and can only receive the latest value, Flow can configure the reply field through the constructor to decide to obtain several previous data updates.
  • Life cycle processing: For LiveData, compared with the way of passing in the LifecycleOwner internal registration life cycle callback when calling the observe function; Flow’s observationcollect The function needs to be called in the coroutine, which means that the life cycle of the coroutine needs to be automatically managed. Otherwise, there may be an error that the coroutine is opened, receives data changes, updates the UI and sends NPE, so the coroutine domain that calls collect needs to be controlled. Scope life cycle, fortunately, Android provides several coroutine scope APIs to open: 1. viewModelScope: Follow the life cycle changes of ViewModel. When the component observed by ViewModel is destroyed and onClear is called, the coroutine is automatically canceled. After the life cycle, Long-term use is generally used when processing data.

2.lifecycleScope: The coroutine started in this scope will be canceled when Lifecycle is destroyed; you can also specify when to start through the when life cycle. If Lifecycle is not at least in the minimum required state, any coroutine running within these blocks will be suspended, note that it is suspend rather than cancellation on destruction, which means resources will still be wasted.

Be sure to pay attention to the difference between the word cancel and suspend. In fact, suspension still has a subscription relationship. When the flow is launched, it will still receive the message and go to the upstream of collect and it will not be cancelled. However, cancellation is the cancellation of the coroutine scope and the collect function will not be executed. .

But we can use repeatOnLifecycle, which cancels when leaving a certain life cycle, and starts a new coroutine when it meets the requirement (that is, the collect function will be re-executed as a new subscriber).

Android official warning: Prefer to use the repeatOnLifecycle API to collect data streams instead of collecting within the launchWhenX API. Because the latter API will suspend the coroutine instead of canceling it when Lifecycle is in the STOPPED state. The upstream stream remains active in the background and may emit new items and consume resources.

  • An initial value needs to be given.
Build StateFlow & amp;ShareFlow

Official example:

To convert ordinary flow to ShareFlow (a type of StateFlow) through the shareIn operator, the following three parameters need to be passed in: (these three parameters)

class NewsRemoteDataSource(...,
    private val externalScope: CoroutineScope,
) {
    val latestNews: Flow<List<ArticleHeadline>> = flow {
        ...
    }.shareIn(
        externalScope,
        replay = 1,
        started = SharingStarted.WhileSubscribed()
    )
}
  • externalScope: CoroutineScope for shared data streams. This scoped function should outlive any consumer to keep the shared data stream active long enough. (When the scope is exceeded, the flow downstream logic is cancelled)

repeatOnLifecycle collects the (upstream) collect function for the life cycle unsubscription flow (in line with opening a new coroutine to re-subscribe). The WhileSubscribed policy configures the subscriber timeout to cancel the flow function (downstream). Match these two, one is a subscriber and the other is Handle the business logic of the subscriber relationship

  • replay: The number of data items to replay (replay) to each new collector. (The value will also be stored when the value is emitted, which can be understood as configuring the buffer size for later “playback”)
  • started: “Start” the behavior policy. 1.WhileSubscribed() When there are active subscribers (the coroutine domain of the observed flow has not been canceled), the flow function will also be active (execute the flow function), and the timeout for the last subscriber’s unsubscription can be configured. The time tocancel the flow function can also be configured to expire (data will be removed from the buffer after a period of time)

2.SharingStarted.Eagerly can start the provider immediately (the flow function runs immediately), and use SharingStarted.Lazily to start sharing data after the first subscriber appears (only when It will run only when subscribed) and the collection will be canceled when the externalScope scope is cancelled.

Conduct Policy Link

In addition, other SharedFlow behaviors can be defined:

  • replay allows you to resend multiple previously emitted values to new subscribers.

  • onBufferOverflow allows you to specify policies for handling situations where the buffer is full of data items to be sent. The default value is BufferOverflow.SUSPEND, which causes the caller to hang. Other options include DROP_LATEST or DROP_OLDEST.

  • Get the number of active collectors through the subscriptionCount property.

  • Clear the data cache via the resetReplayCache function, for use when you do not want to replay the latest information that has been sent to the data stream.

Original link: (StateFlow & ShareFlow) VS (Flow & LiveData) – Nuggets (juejin.cn)

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 139228 people are learning the system

syntaxbug.com © 2021 All Rights Reserved.