我们可以使用LiveData而不会失去任何价值吗?

时间:2019-05-12 08:58:39

标签: android android-livedata

我想使用LiveData处理自定义视图与其包装片段之间的通知,因为它已经具有生命周期意识。但是,似乎LiveData可能会丢失值:它只会更新为最新状态,并且在观察者处于非活动状态时也不会触发值。

我已经从Google代码示例中查看了SingleLiveEvent purpose,但是该解决方案似乎尚未经过严格的测试,并且ticket仍在进行改进该解决方案的最新尝试。 / p>

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

是否有针对此的现有解决方案?如果我尝试实现它,那么可以肯定的是,我至少会陷入一种反模式。

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

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

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

您有什么想法和建议?

另外,请注意,我需要从包装到片段(ChessBoard)中的组件到另一个片段(ChessHistory)的通信。因此他们都知道生命周期。

1 个答案:

答案 0 :(得分:0)

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

/**
* 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()以便接收所有通知。

不确定这是否足以满足您的需求,但我希望它能为您提供帮助或为您提供一些有关如何实现自己的方法的想法。