Как очистить сохраненное значение LiveData?

по данным документация LiveData:

класс LiveData предоставляет следующие преимущества:

...

всегда в курсе данных: если жизненный цикл начинается снова (например, действие возвращается в начальное состояние из заднего стека), он получает последние данные о местоположении (если это еще не произошло).

но иногда мне не нужна эта функция.

например, у меня после LiveData в ViewModel и наблюдатель в деятельности:

//LiveData
val showDialogLiveData = MutableLiveData<String>()

//Activity
viewModel.showMessageLiveData.observe(this, android.arch.lifecycle.Observer { message ->
        AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK") { _, _ -> }
                .show()
    })

теперь после каждого поворота появится старый диалог.

есть ли способ очистить сохраненное значение после его обработки или это неправильное использование LiveData вообще?

4 ответов


ответ Алекса в комментариях-я думаю, что именно то, что вы ищете. Существует пример кода для класса SingleLiveEvent. Назначение этого класса описывается следующим образом:

наблюдаемый жизненный цикл, который отправляет только новые обновления после подписка, используемая для таких событий, как навигация и сообщения Snackbar.

Это позволяет избежать общей проблемы с событиями: при изменении конфигурации (как вращение) обновление может быть выдано, если наблюдатель активен. Это LiveData вызывает только наблюдаемое, если есть явный вызов setValue () или call ().


в моем случае SingleLiveEvent не помогает. Я использую этот код:

private MutableLiveData<Boolean> someLiveData;
private final Observer<Boolean> someObserver = new Observer<Boolean>() {
    @Override
    public void onChanged(@Nullable Boolean aBoolean) {
        if (aBoolean != null) {
            // doing work
            ...

            // reset LiveData value  
            someLiveData.postValue(null);
        }
    }
};

Я не уверен, будет ли это работать в вашем случае, но в моем случае (увеличение/уменьшение количества элементов в комнате, нажав на просмотры) удаление наблюдателя и проверка, есть ли активные наблюдатели, позвольте мне выполнить эту работу:

LiveData<MenuItem> menuitem = mViewModel.getMenuItemById(menuid);
menuitem.observe(this, (MenuItem menuItemRoom) ->{
                menuitem.removeObservers(this);
                if(menuitem.hasObservers())return;

                // Do your single job here

                });
});  

вам нужно использовать SingleLiveEvent для этого случая

class SingleLiveEvent<T> : MutableLiveData<T>() {

    private val pending = AtomicBoolean(false)

    @MainThread
    override fun observe(owner: LifecycleOwner, observer: Observer<T>) {

        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
        }

        // Observe the internal MutableLiveData
        super.observe(owner, Observer<T> { t ->
            if (pending.compareAndSet(true, false)) {
                observer.onChanged(t)
            }
        })
    }

    @MainThread
    override fun setValue(t: T?) {
        pending.set(true)
        super.setValue(t)
    }

    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    fun call() {
        value = null
    }

    companion object {
        private const val TAG = "SingleLiveEvent"
    }
}

и внутри вас класс viewmodel создает объект типа:

 val snackbarMessage = SingleLiveEvent<Int>()