在其他任何事情之前,我不是要求解决这个问题的解决方案(代码),我要求对我在LiveData中的理解进行修正,因为我认为我错过了一些东西。
据我所知,LiveData的onActive函数每次在活动或片段的onCreate方法中激活Observer(LifeCycleOwner)时都会触发。
这是我现在处理的问题。
我使用Android导航组件,我有我的活动A,其中包含一个导航图,在此图中,两个片段共享公共逻辑,因此,为了简单起见,我使用ViewModel而不是创建用于彼此之间通信的接口,称之为ActivityAViewModel。
现在,此VM包含以下内容。
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并检测到变化。
有没有办法防止这两个片段收到结果?我的意思是,当这两个人中的一个收到结果时,另一个人不会听吗?
您可能希望相应地设计此事件,这与Jeel共享的博客文章中讨论的事件包装器非常相似。
基本的想法是Event只会消耗一次。然后,您可以使用LiveData包装它。当您在LiveData中设置新事件时,观察者将收到通知,在第一次消耗新事件后,后续消耗将不会返回任何值。