android - 我们可以在不损失任何值(value)的情况下使用 LiveData 吗?

标签 android android-livedata

我想使用 LiveData 来处理自定义 View 及其包装 fragment 之间的通知类型,因为它已经具有生命周期意识。但似乎 LiveData 可能会丢失值:它只会更新到其最新状态,并且在其观察者处于非 Activity 状态时也不会触发值。

我看过 SingleLiveEvent purpose来自 Google 代码示例,但该解决方案似乎尚未经过实战测试,并且 ticket对最近改进解决方案的尝试仍然开放。

所以我正在寻找一种简单的方法来获得事件通知,同时不用担心生命周期(这就是我选择 LiveData 作为第一个解决方案的原因),并且可以处理多个观察者。

有现成的解决方案吗?如果我尝试实现它,我肯定至少会陷入反模式。

一种简单的方法(也许太简单了)是使用回调:但问题是我的组件中的多个回调需要此功能,导致我的架构很差。而且,我想要一个订阅系统,这意味着可以有多个观察者。

另一种方法是使用 RxJava 并将其转换为 LiveData,使用 LiveDataReactiveStreams.fromPublisher() :但现在的问题是我是获取所有值还是只获取最后一个值。这是我能处理的最接近的解决方案。

作为一个有趣的选择,可能有 AutoDisposeRxLifecycle .我发现了一个有趣的资源:Blog post on LiveData

您有什么想法、建议?

另外,请注意,我需要从包装到 fragment (ChessBoard) 的组件到另一个 fragment (ChessHistory) 的这种通信。所以他们都知道生命周期。

最佳答案

这并不理想,但这对我有用:

/**
* This LiveData will deliver values even when they are 
* posted very quickly one after another.
*/
class ValueKeeperLiveData<T> : MutableLiveData<T>() {

    private val queuedValues: Queue<T> = LinkedList<T>()

    @Synchronized
    override fun postValue(value: T) {
        // We queue the value to ensure it is delivered 
        // even if several ones are posted right after.
        // Then we call the base, which will eventually
        // call setValue().
        queuedValues.offer(value)
        super.postValue(value)
    }

    @MainThread
    @Synchronized
    override fun setValue(value: T) {
        // We first try to remove the value from the queue just
        // in case this line was reached from postValue(),
        // otherwise we will have it duplicated in the queue.
        queuedValues.remove(value)

        // We queue the new value and finally deliver the
        // entire queue of values to the observers.
        queuedValues.offer(value)
        while (!queuedValues.isEmpty())
            super.setValue(queuedValues.poll())
    }
}

此解决方案的主要问题是,如果在通过 super.setValue() 传递值时观察者处于非 Activity 状态,那么无论如何这些值都会丢失。然而,它解决了当多个新值很快发布时丢失值的问题——在我看来,这通常比丢失值更大的问题,因为你的观察者不活跃。毕竟,您始终可以从非生命周期感知对象执行 myLiveData.observeForever() 以接收所有通知。

不确定这对您是否足够,但我希望它可以帮助您或给您一些关于如何实现您自己的方法的想法。

关于android - 我们可以在不损失任何值(value)的情况下使用 LiveData 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56097647/

相关文章:

android - OnEditorActionListener 在 SenseUI 键盘上使用相同的 eventTime 调用了两次

android - SKCurrentPositionListener 不工作,在 SKMaps 中未达到 onCurrentPositionUpdate

android - 带边框的透明圆圈

android - 使用 Room 实时查询进行生命周期状态管理

java - 为什么我不能在 ormlite 中使用自定义 DAO 类?

android - 如何提供具有 Dagger 依赖项的 Activity 上下文?

java - 为什么 LiveData setValue 或 PostValue 在 View 中只触发一次 onChange?

android - 屏幕旋转时的 ViewModel 更新

android - 修改从 Room 获取的 LiveData 项目

java - 注册观察者与设置处理程序