当前位置: 首页 > 知识库问答 >
问题:

LiveData-使用SingleLiveCase进行转换

咸承教
2023-03-14

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

我遇到的情况是,这里建议的SingleLiveEvent是相关的,即我返回一个错误,我只想显示一次警报。在向活动发送值之前,我需要将错误映射到视图中更合适的对象。我使用了一个转换来实现这一点。

最后,我有一个ViewModel,看起来像:

public LiveData<ViewState> getStateForView() {
    final LiveData<NetworkState> liveState = myRepository.getState();
    return Transformations.map(liveState, myMapper::map);
}

在我的存储库中,我使用的是SingleLive事件:

public LiveData<NetworkState> getState() {
    myNetworkState = new SingleLiveEvent<>();
    return myNetworkState;
}

这很有效,但我注意到,当方向多次改变时,我的事件不会一直传播。调试时,我注意到观察者注册和移除之间没有对称性:

  • 注册时,SingleLiveEvent的观察者是SingleLiveEvent中的匿名观察者类

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

发生的事情是,我的初始观察者从未从SingleLiveEvent的观察者中移除(因此,如果方向多次更改,我的SingleLiveEvent就有多个观察者)。

我不明白为什么在删除时这不是同一个观察者。当在没有转换步骤的情况下复制它时,就没有这样的问题。

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

共有1个答案

金霄
2023-03-14

我发现这是因为Transformations使用MediatorLiveData,它使用SingleLiveEvent作为引用源。该源用于注册和移除自身作为观察者的身份。

然而,SingleLiveEvent在注册时引入了一个中间观察者。SingleLiveEvent引用了这个中间观察者,不知道MediatorLiveData

在删除时,MediatorLiveData尝试将自己从SingleLive事件中注销为观察者。由于SingleLive事件不知道它,所以它保留了中间观察者。

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

我不知道我是否遗漏了什么,或者MediatorLiveData是否不能与SingleLiveEvent一起使用,但我找到了一个解决具体问题的方法。

我在SingleLiveCase中添加了对中间观察者的引用,并且我重写了它的远程观察者()方法来删除中间观察者,而不是(仅)删除MediatorLiveData。我对这个解决方案不太有信心,因为我不熟悉LiveData的内部结构。特别是,这个解决方案只有在只有MediatorLiveData作为观察者使用时才有效(也就是说,如果活动观察到SingleLiveCase,则不适用),并且只有在只有一个观察者的情况下才有效(这在SingleLiveCase的情况下才有意义)。可能还有其他限制。

下面是我添加的删除右观察者的代码(singleLiveEventIntermediateObserver是在observe()方法中实例化的匿名observer):

@Override
public void removeObserver(@NonNull Observer<T> observer) {
    super.removeObserver(observer);
    if (this.singleLiveEventIntermediateObserver != null) {
        super.removeObserver(this.singleLiveEventIntermediateObserver);
    }
}
 类似资料:
  • 我想将XMl转换为另一种XMl格式。假设我在ats中有一个逻辑。埃姆沃。使改变TransformXml java文件如何集成以在camel上下文输入中转换tis(file:///d:/in)是xml文件,我想将其另存为xml。我已经将此文件作为bean类添加到camel

  • 我正在尝试使用JOLT(使用NiFi JoltTransformJson处理器)将JSON转换为不同的格式。对于单个JSON记录,正在使用的JOLT在JOLT应用程序演示中运行良好,而如果我使用多个JSON记录执行,那么我在JOLT应用程序演示中没有得到预期的输出。有人能告诉我在JOLT规范中需要做哪些额外的更改来处理多个JSON记录吗? 示例输入json JOLT使用: 预期输出JSON:

  • 问题内容: 我需要将传入日期字符串格式“ 20130212”(YYYYMMDD)转换为12/02/2013(DD / MM / YYYY) 使用。我知道没有这种方法可以做到这一点。谁能帮我? 转换不包含: 问题答案: Java中的ThreadLocal除了编写不可变的类外,还是一种实现线程安全的方法。由于SimpleDateFormat不是线程安全的,因此可以使用ThreadLocal使其成为线程

  • 问题内容: 您如何使用Paramiko传输完整目录?我正在尝试使用: 这给了我这个错误- 问题答案: 您将需要像使用python在本地一样进行此操作(如果您未使用Shutils)。 结合,和和。您可能还需要检查每个文件和目录,具体取决于您是否要解析符号链接。

  • 使用ByteBuddy,我可以通过调用另一个实例方法并转换结果来实现一个实例方法吗? 例如(玩具): 鉴于上述情况,我能否实现,以便它调用并返回返回字符串的长度?也就是说,好像它是: 我天真地尝试了以下方法: 然而,看起来我的想法是错误的,;它看起来像是在生成的实例上调用的。 我还试过一个拦截器: 与: 这运行了,但产生了毫无意义的结果,在中设置断点和/或添加打印语句表明它永远不会被调用;所以很明

  • 问题内容: 我有标准ISO 8601格式的日期/时间值,例如 2010-07-26T11:37:52Z 。 我想要日期 为2010年7月26日(dd-mon-yyyy) 。我该怎么做? 问题答案: 构造两个SimpleDateFormat对象。首先,您将值从()解析为Date对象,第二次用于将Date对象转换为字符串,例如 解析可能会引发ParseException,因此您需要捕获并处理它。