android - LiveData - 将 SingleLiveEvent 与转换结合使用

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

我现在正在使用最新的 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 中的匿名观察者类

debug of registration

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

debug of removal

发生的情况是,我的初始观察者永远不会从 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/

相关文章:

android - 膨胀自定义 View 类时出错

android - Wi-Fi P2P。通知所有同龄人某件事

android - 在 System.getenv 中找不到 Github Secret

events - 将 UserControl 卸载事件绑定(bind)到 ViewModel

android - 无法在后台线程上调用 observeForever

Android Architecture 组件 LiveData - 如何将 broadcastReceivers 绑定(bind)到生命周期

android - java.lang.RuntimeException : Unable to start activity, java.lang.NullPointerException 异常

android - 如何在 mvvm android 中显示对话框

design-patterns - 使用 MVVM/WPF 进行域驱动设计

android - 调用 Fragment 构造函数导致异常。导航架构组件