我现在正在使用最新的 Android 架构组件,尤其是 ViewModel 和 LiveData。
我的情况是 SingleLiveEvent建议here是相关的,即我正在返回一个错误,我只想显示一次警报。在向 Activity 发出值之前,我需要将我的错误映射到更适合 View 的对象。我正在为此使用转换。
所以最后,我有一个如下所示的 ViewModel:
public LiveData<ViewState> getStateForView() {
final LiveData<NetworkState> liveState = myRepository.getState();
return Transformations.map(liveState, myMapper::map);
}
在我的存储库中我使用 SingleLiveEvent 的地方:
public LiveData<NetworkState> getState() {
myNetworkState = new SingleLiveEvent<>();
return myNetworkState;
}
这工作得很好,但我注意到当方向多次改变时,我的事件并没有一直传播。调试时,我注意到观察者注册和移除之间没有对称性:
- 在注册时,我的 SingleLiveEvent 的观察者是我的 SingleLiveEvent 中的匿名观察者类
- 在删除时,要从我的 SingleLiveEvent 中删除的观察者是一个 MediatorLiveData(它实际上是在我的 SingleLiveEvent 中观察较早的匿名类)
发生的情况是,我的初始观察者永远不会从 SingleLiveEvent 的观察者中移除(因此,如果方向多次更改,我的 SingleLiveEvent 有多个观察者)。
我不明白为什么在删除时这不是同一个观察者。在没有转换步骤的情况下复制它时,没有这样的问题。
有没有人对这种行为有所暗示? SingleLiveEvent(不是框架的一部分)和 Transformations 不应该一起工作吗?
最佳答案
我发现这是因为 Transformations
使用MediatorLiveData
,它使用 SingleLiveEvent
作为引用来源。此源用于注册和删除自己作为观察者。
然而,SingleLiveEvent
在注册时引入中间观察员。 SingleLiveEvent
引用这个中间观察者并且不知道 MediatorLiveData
.
在删除时,MediatorLiveData
试图从 SingleLiveEvent
注销自己作为观察者的注册.自 SingleLiveEvent
不知道它,它保留中间观察者。
最后,这个过程是不对称的,随着时间的推移(当用户转动手机时),SingleLiveEvent
观察者越来越多。
我不知道我是否遗漏了什么或者 MediatorLiveData
不能与 SingleLiveEvent
一起使用,但我找到了针对我的特定问题的解决方案。
我在 SingleLiveEvent
中添加了对中间观察者的引用我已经覆盖了它的 removeObserver()
删除中间观察者而不是(仅)MediatorLiveData
的方法.我对这个解决方案不太有信心,因为我不熟悉 LiveData
的内部结构。 .特别是,此解决方案仅在 SingleLiveEvent
时才有效。仅与 MediatorLiveData
一起使用作为观察者(即如果 Activity 观察 SingleLiveEvent
则不是),并且仅当存在单个观察者时(这在 SingleLiveEvent
的情况下才有意义)。可能还有其他限制。
这是我添加的用于删除右观察者的代码(singleLiveEventIntermediateObserver
是在 Observer
方法中实例化的匿名 observe()
):
@Override
public void removeObserver(@NonNull Observer<T> observer) {
super.removeObserver(observer);
if (this.singleLiveEventIntermediateObserver != null) {
super.removeObserver(this.singleLiveEventIntermediateObserver);
}
}
关于android - LiveData - 将 SingleLiveEvent 与转换结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47469398/