LiveData - 将SingleLiveEvent与转换一起使用

时间:2017-11-24 08:44:16

标签: android mvvm android-architecture-components android-livedata

我现在正在使用最新的Android架构组件,尤其是ViewModel和LiveData。

我遇到SingleLiveEvent建议here相关的情况,即我返回错误,我只想显示一次警报。在向Activity发出值之前,我需要将我的错误映射到视图的更合适的对象。我正在使用转换。

所以最后,我有一个看起来像的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中的匿名Observer类

debug of registration

  • 在删除时,要从我的SingleLiveEvent中删除的观察者是MediatorLiveData(实际上是在我的SingleLiveEvent中观察早期的匿名类)

debug of removal

我的初始观察者永远不会从SingleLiveEvent的观察者中移除(所以如果方向多次改变,我的SingleLiveEvent有多个观察者)。

我无法弄清楚为什么在移除时这不是同一个观察者。在没有转换步骤的情况下再现它时,没有这样的问题。

有没有人对这种行为有所暗示? SingleLiveEvent(不是框架的一部分)和转换不应该一起工作吗?

1 个答案:

答案 0 :(得分:2)

我发现这是因为Transformations使用MediatorLiveDataSingleLiveEvent使用SingleLiveEvent作为参考来源。该来源用于作为观察者注册和删除自己。

但是,SingleLiveEvent在注册时引入了一名中间观察员。 MediatorLiveData引用此中间观察者,但不知道MediatorLiveData

在删除时,SingleLiveEvent尝试从SingleLiveEvent注销自己作为观察者。由于SingleLiveEvent不知道它,它保留了中间观察者。

最后,这个过程并不是对称的,随着时间的推移(当用户转动手机时),MediatorLiveData有越来越多的观察者。

我不知道我是否遗漏了某些内容,或SingleLiveEvent是否与SingleLiveEvent不一致,但我找到了针对我的具体问题的解决方案。

我在removeObserver()中添加了对中间观察者的引用,并且我已经覆盖了它的MediatorLiveData方法以删除中间观察者而不是(仅)LiveData。我对这个解决方案不太自信,因为我不熟悉SingleLiveEvent的内部。特别是,此解决方案仅在MediatorLiveData仅与SingleLiveEvent作为观察者使用时才有效(即,如果活动观察SingleLiveEvent),并且仅当有一个观察者时(这在singleLiveEventIntermediateObserver)的情况下是有意义的。可能还有其他限制。

以下是为删除正确的观察者而添加的代码(Observerobserve()方法中实例化的匿名@Override public void removeObserver(@NonNull Observer<T> observer) { super.removeObserver(observer); if (this.singleLiveEventIntermediateObserver != null) { super.removeObserver(this.singleLiveEventIntermediateObserver); } }

domain1.com