6

我最近在我的 Android 应用程序中采用了 MVVM。为了解决应用程序生命周期的潜在问题,谷歌发布了 LiveData。

LiveData 的使用有不同的场景,正如Jose Alcérreca 撰写的中篇文章所指出的,您可以使用 SingleLiveEvent 或类似事件包装器模式的东西。

我想确保SingleLiveEvent事件包装器模式,这是在 Android MVVM 架构中与 LiveData 一起使用的最佳实践。而且我发现今年(2018 年)的Google I/O 应用程序没有使用SingleLiveEvent,而是使用事件包装器模式

之前我在项目android-architecture上开了一个issue,起初我正在寻求官方回复,但似乎根本没有任何评论。因此,我想听听已经使用这些东西的开发人员的建议并对此进行反思。

请分享您的宝贵经验,在此先感谢您。

4

2 回答 2

4

我不喜欢它,SingleLiveEvent因为它仅限于一个观察者,但你也可以添加许多观察者,所以它很容易出错。

但在一个非常简单的场景中(比如你提到的 todo 应用程序),它可能是比事件包装器模式更好的选择。

在复杂的场景中,事件包装器模式会是更好的选择,但它也有一些限制。此实现假设您只有一个主要消费者(请参阅参考资料getContentIfNotHandled)。因此,我认为与多个观察者打交道将导致样板文件决定哪个是主要消费者,或者我应该何时调用getContentIfNotHandledor peekContent

但是,所有这些限制都可以通过您自己的实现来解决。

例如,这是一个支持多个观察者的扩展版本SingleLiveEvent

public class SingleLiveEvent<T> extends MutableLiveData<T> {
private LiveData<T> liveDataToObserve;
private final AtomicBoolean mPending = new AtomicBoolean(false);

public SingleLiveEvent() {
    final MediatorLiveData<T> outputLiveData = new MediatorLiveData<>();
    outputLiveData.addSource(this, currentValue -> {
        outputLiveData.setValue(currentValue);
        mPending.set(false);
    });
    liveDataToObserve = outputLiveData;
}

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        liveDataToObserve.observe(owner, t -> {
            if(mPending.get()) {
                observer.onChanged(t);
            }
        });
    }

    @MainThread
    public void setValue(T value) {
        mPending.set(true);
        super.setValue(value);
    }
}

如您所见,这SingleLiveEvent与 vs 事件包装器模式无关,这完全取决于。就个人而言,我使用其他模式(如 React/Flux 世界中存在的模式)来处理状态。

请记住,软件工程中没有灵丹妙药。

于 2018-10-13T06:15:22.707 回答
0

SingleLiveData 仅限于一个观察者,本文介绍的 EventLiveData支持多个观察者。

您可以像使用常规实时数据一样使用它。没有黑客攻击或给代码增加不必要的复杂性。

implementation 'com.rugovit.eventlivedata:eventlivedata:1.0'

MutableEventLiveData<String>  eventLiveData =new MutableEventLiveData<>(); 
viewModel.event.observe(this, Observer {
    // ...
})
 

它是 livedata 的扩展,支持 livedata 的所有功能。与其他解决方案不同,它支持多个观察者

Github 链接:https ://github.com/rugovit/EventLiveData

于 2020-01-09T03:48:13.490 回答