代码之家  ›  专栏  ›  技术社区  ›  Carter Chen

事件包装模式是否取代使用singleliveevent?

  •  1
  • Carter Chen  · 技术社区  · 7 年前

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

    LiveData的使用有不同的场景,如 medium article wrote by Jose Alcérreca 您可以使用singleliveevent或类似事件包装模式的东西。

    我想确定 SingleLiveEvent ,或者 event wrapper pattern 在android mvvvm架构中,哪一个是与livedata一起使用的最佳实践。我找到了 Google I/O app 今年(2018年)没有使用 单一事件 ,它使用 事件包装模式 相反。

    以前我开过一家 issue 关于项目 android-architecture 一开始,我在寻求一个正式的答复,但似乎没有任何评论。因此,我想听听已经使用这些东西并对其进行思考的开发人员的建议。

    请分享您宝贵的经验,提前感谢。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Saeed Masoumi    7 年前

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

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

    在复杂的场景中,事件包装模式是更好的选择,但它也有一些限制。 This implementation 假设你只有一个 主要的 消费者(见) getContentIfNotHandled )因此,我认为与多个观察者打交道将导致样板文件决定哪一个是主要的消费者,或者我应该何时打电话给他们。 getContentifNothandLED 或 peekContent .

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

    例如,这里有一个 extended version 属于 单一事件 支持多个观察员:

    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);
        }
    }
    

    如你所见,这不是关于 单一事件 vs事件包装模式,这一切都取决于。就我个人而言,我使用其他模式(如react/flux世界中存在的模式)来处理状态。

    请记住,在软件工程中没有“银弹”。