在这种情况下,LiveData如何工作?

问题描述 投票:0回答:1

在其他任何事情之前,我不是要求解决这个问题的解决方案(代码),我要求对我在LiveData中的理解进行修正,因为我认为我错过了一些东西。

据我所知,LiveData的onActive函数每次在活动或片段的onCreate方法中激活Observer(LifeCycleOwner)时都会触发。

这是我现在处理的问题。

我使用Android导航组件,我有我的活动A,其中包含一个导航图,在此图中,两个片段共享公共逻辑,因此,为了简单起见,我使用ViewModel而不是创建用于彼此之间通信的接口,称之为ActivityAViewModel。

现在,此VM包含以下内容。

  • 此VM的私有MediatorLiveData,用于向其报告值
  • 一个公共函数,它将此MediatorLiveData作为LiveData返回,从而阻止UI控制器修改其值
  • 执行一些功能的函数,此工作返回一个LiveData,一个Transformation用于工作返回的LiveData,返回必要的UI数据。
  • 它看起来像这样:

ActivityAViewModel.kt

// Private Mediator LiveData
private val mediatorLD = MediatorLiveData<Boolean>()

// Public immutable access of the mediator LiveData
fun mediatorLD(): LiveData = mediatorLD

// Representation of what the transformation is doing.
fun doFoo() {
   val workLD: LiveData<WrapperClass<Boolean>> = repository.someWork()
   Transformations.map(workLD) { wrappedResult ->
      mediatorLD.postValue(wrappedResult.myBoolean)
   }
}

现在,两个UI控制器MyFragmentB.kt和MyFragmentC.kt正在观察MutableLiveData的LiveData版本,我遇到的问题是,当MyFragmentB执行doFoo()时,它会相应地接收结果,没有问题,但是当我导航到MyFragmentC.kt,向C报告相同的结果,反之亦然。

我不希望这种情况发生,如果片段已经观察到这种变化,我不希望C听取这种变化。

我有点理解为什么会这样。

据我所知,LiveData的onActive函数每次在活动或片段的onCreate方法中激活Observer(LifeCycleOwner)时都会触发。

由于已使用postValue检测到更改,因此ViewModel正在等待其观察者处于活动状态以便分派结果。

当执行到另一个片段的导航时,观察者准备就绪,触发onActive并检测到变化。

有没有办法防止这两个片段收到结果?我的意思是,当这两个人中的一个收到结果时,另一个人不会听吗?

android android-architecture-components android-livedata
1个回答
1
投票

您可能希望相应地设计此事件,这与Jeel共享的博客文章中讨论的事件包装器非常相似。

https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

基本的想法是Event只会消耗一次。然后,您可以使用LiveData包装它。当您在LiveData中设置新事件时,观察者将收到通知,在第一次消耗新事件后,后续消耗将不会返回任何值。

© www.soinside.com 2019 - 2024. All rights reserved.