Android:实时数据跳过值

ash*_*jan 4 android backpressure android-livedata

我正在使用实时数据将状态从视图模型发布到片段,这可能会导致状态频繁发布。但是可变实时数据正在跳过初始值并采用可用的最新值。

一篇文章谈到了这个特性,但是有没有办法处理这种情况,比如RxJava 中的 Flowable或设置背压策略,或者我是否需要回到使用 RxJava 并处理基于生命周期的发布?

以下是显示此行为的示例代码。发布了 1 到 10 的值,但只收到了两个值,0 和 10。我们可以在 Live Data 中更改此行为,还是应该为此使用 RxJava?

片段(订阅者):

class ParentFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel = ViewModelProviders.of(
            this, ParentViewModelFactory(this, null)
        ).get(ParentViewModel::class.java)

        viewModel.fastLiveData.observe(this, Observer {
            Timber.i(it.toString())
        })

        viewModel.startPublishing()
    }
}
Run Code Online (Sandbox Code Playgroud)

查看模型(发布者):

class ParentViewModel(private val savedState : SavedStateHandle)
    : ViewModel<ParentState>() {

    val fastLiveData : MutableLiveData<Int> = MutableLiveData(0)

    fun startPublishing() {
        for(x in 1..10) {
            Timber.i(x.toString())
            fastLiveData.postValue(x)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出 :

(ParentViewModel.kt:30)#startPublishing: 1
(ParentViewModel.kt:30)#startPublishing: 2
(ParentViewModel.kt:30)#startPublishing: 3
(ParentViewModel.kt:30)#startPublishing: 4
(ParentViewModel.kt:30)#startPublishing: 5
(ParentViewModel.kt:30)#startPublishing: 6
(ParentViewModel.kt:30)#startPublishing: 7
(ParentViewModel.kt:30)#startPublishing: 8
(ParentViewModel.kt:30)#startPublishing: 9
(ParentViewModel.kt:30)#startPublishing: 10
(ParentFragment.kt:57)#onChanged: 0
(ParentFragment.kt:57)#onChanged: 10
Run Code Online (Sandbox Code Playgroud)

Mus*_*han 5

原因是你正在使用 postValue()

  • postValue 将在后台线程上设置该值,并在大量发射的情况下设置最新值。
  • setValue 将在主线程上设置您的值

如果你会改变,fastLiveData.setValue(x)你会得到你想要的行为。

  • 这可能会误导理解。`postValue` 可以在后台使用,值将在主线程异步设置。`setValue` 将立即在当前线程上设置值,但当前线程*应该*主线程。 (2认同)

San*_*Lee 1

使用RxJavaLiveData旨在通过主线程在视图层中进行观察。LiveData对于观察者来说,消耗超出屏幕刷新率或人眼可以处理的速度是没有意义的。

在单个项目中同时使用RxJavaLiveData是合理的设计选择。互联网上应该有几篇文章和代码示例,这是我刚刚找到的一篇: https: //proandroiddev.com/mvvm-architecture-using-livedata-rxjava-and-new-dagger-android-injection-639837b1eb6c