Does event wrapper pattern replace the use of SingleLiveEvent?
Asked Answered
M

2

6

I'm adopting MVVM to my Android apps recently. In order to solve the problems underlying with the lifecycle of an app, Google had released LiveData.

The usage of LiveData has different scenarios, as pointed out in the medium article wrote by Jose Alcérreca, you can use SingleLiveEvent or something like the event wrapper pattern.

I want to make sure the SingleLiveEvent, or the event wrapper pattern, which one would be the best practice to use with LiveData in Android MVVM architecture. And I found the Google I/O app of this year(2018) have no usages of SingleLiveEvent, it uses event wrapper pattern instead.

Previously I have opened an issue on the project android-architecture, at first I'm seeking an official reply, but it seems to have no comments at all. As a result, I would like to hear the advice from the developers who already use these stuff and have reflections on it.

Please share your precious experiences, thank you in advance.

Maes answered 13/10, 2018 at 2:25 Comment(0)
H
3

I'm not a fan of SingleLiveEvent because it restricted to one observer but you can add many observers as well, so it can be error-prone.

But in a very simple scenario(like the todo app that you mentioned), it can be a better option than event wrapper pattern.

In a complex scenario, event wrapper pattern would be a better option, but it also has some limitations. This implementation assumes you only have one main consumer (see getContentIfNotHandled). So, I think dealing with multiple observers will cause boilerplate to decide which one is the main consumer or when I should call getContentIfNotHandled or peekContent.

But, All these limitations can be fixed with your own implementation.

For example here is an extended version of SingleLiveEvent that supports multiple observers:

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

As you see, It's not about SingleLiveEvent vs event wrapper pattern, It all depends. Personally, I use other patterns (like patterns existing in React/Flux world) for dealing with states.

Keep in mind that there is no silver bullet in software engineering.

Hundredweight answered 13/10, 2018 at 6:15 Comment(2)
I see. Although LiveData cannot be modified, we can decide how to use it and there is not only a way. Thank you for your reply :)Maes
How is your code supporting multiple observers? I can't spot itAutogenesis
C
0

SingleLiveData is restricted to one observer, EventLiveData described in this article supports multiple observers.

You use it just like regular live data. No hacking or adding unnecessary complexity to code.

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

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

It is extension of livedata and supports every feature of livedata. Unlike other solutions this supports multiple observers.

Github link: https://github.com/rugovit/EventLiveData

Conciliator answered 9/1, 2020 at 3:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.