我们可以在不损失任何价值的情况下使用LiveData吗?
我希望使用LiveData来处理定制视图及其包装片段之间的通知类型,因为它已经具有生命周期感知功能。但似乎LiveData可能会丢失值:它只会更新到其最新状态,也不会在其观察器处于非活动状态期间激发值。
我已经查看了Google代码示例中的SingleLiveEvent purpose,但该解决方案似乎尚未经过战斗测试,而且ticket最近仍在尝试改进该解决方案。
所以我正在寻找一种简单的方式来获得事件的通知,同时又不担心生命周期(这就是我选择LiveData作为第一个解决方案的原因),并且可以处理多个观察者。
对此是否有现有的解决方案?如果我尝试实现它,我肯定至少会陷入反模式。
一种简单的方法(可能太容易了)是使用回调:但问题是,我的组件中的几个回调都需要这个功能,这导致我陷入了一个糟糕的体系结构。此外,我还想要一个订阅系统,这意味着可以有不止一个观察者。另一种方法是使用RxJava并使用LiveDataReactive Streams.from mPublisher()将其转换为LiveData:但现在的问题是我将获得所有值还是只获得最后一个值。这是我能处理的最接近的解决方案。
作为一个有趣的替代方案,可以有AutoDispose或RxLifecycle。和我发现的一个有趣的资源:Blog post on LiveData
您的想法、建议是什么?
此外,请注意,我需要从包装在片段(棋盘)中的组件到另一个片段(棋盘)的通信。因此它们都具有生命周期意识。解决方案
不太理想,但这对我很管用:
/**
* 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()
传送值时处于非活动状态,则无论如何,这些值都将丢失。然而,它解决了当几个新的帖子非常快地发布时失去价值的问题-在我看来,这通常比因为你的观察者不活跃而失去价值更大的问题。毕竟,您始终可以从非生命周期感知对象执行myLiveData.observeForever()
操作,以便接收所有通知。
我不确定这是否足以满足您的需求,但我希望它能帮助您,或为您提供一些有关如何实现您自己的方法的想法。
相关文章