Заменяет ли шаблон оболочки событий использование SingleLiveEvent?

Я недавно ввел MVVM в свои приложения для Android. Чтобы решить проблемы, связанные с жизненным циклом приложения, Google выпустил LiveData.

Использование LiveData имеет разные сценарии. Как указывается в средней статье, написанной Хосе Альсеррека, вы можете использовать SingleLiveEvent или что-то вроде шаблона оболочки событий.

Я хочу убедиться, что это SingleLiveEvent или шаблон оболочки событий, который лучше всего использовать с LiveData в архитектуре Android MVVM. И я обнаружил, что приложение ввода-вывода Google этого года (2018) не использует SingleLiveEvent, вместо этого оно использует шаблон оболочки событий.

Ранее я открыл вопрос о проекте android-Architecture, сначала я искал официальный ответ, но, похоже, у него вообще нет комментариев. В результате я хотел бы услышать совет от разработчиков, которые уже используют эти вещи и размышляют над этим.

Пожалуйста, поделитесь своим ценным опытом, заранее спасибо.

1 ответ

Решение

Я не фанат SingleLiveEvent потому что он ограничен одним наблюдателем, но вы также можете добавить много наблюдателей, поэтому он может быть подвержен ошибкам.

Но в очень простом сценарии (например, в приложении todo, которое вы упомянули) это может быть лучшим вариантом, чем шаблон оболочки событий.

В сложном сценарии шаблон оболочки событий будет лучшим вариантом, но он также имеет некоторые ограничения. Эта реализация предполагает, что у вас есть только один основной потребитель (см. getContentIfNotHandled). Итак, я думаю, что работа с несколькими наблюдателями приведет к тому, что шаблон решит, кто из них является основным потребителем или когда мне следует позвонить getContentIfNotHandled или же 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) для работы с состояниями.

Имейте в виду, что в разработке программного обеспечения нет серебряной пули.

SingleLiveData ограничен одним наблюдателем, EventLiveData, описанный в этой статье, поддерживает несколько наблюдателей.

Вы используете его как обычные данные в реальном времени. Никакого взлома или добавления ненужной сложности в код.

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

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

Это расширение Liveata и поддерживает все функции Liveata. В отличие от других решений, это поддерживает несколько наблюдателей.

Ссылка на Github: https://github.com/rugovit/EventLiveData