MutableLiveData не уведомляет наблюдателя - PullRequest
1 голос
/ 30 апреля 2019

Я пытаюсь использовать MutableLiveData с предварительно заполненным значением из базы данных, но Observer всегда возвращает null как book. Мне нужно сохранить его как MutableLiveData, а НЕ LiveData, потому что я должен установить его программно в некоторых местах. Поэтому я звоню setValue с LiveData, полученным из БД. Код:

ViewModel:

private final MutableLiveData<Book> bookLiveData;

public MyViewModel(@NonNull Application application) {
    super(application);
    ...
    book = new MutableLiveData<>();
    bookLiveData.setValue(bookRep.getBookLiveData().getValue());
    ....
}

Fragment:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    ...
    getActivity().getBookLiveData().observe(getViewLifecycleOwner(), book -> {
            ... // When fragment is created, book is always null here
    });
}

Может кто-нибудь сказать мне, почему Book ноль в наблюдателе? Я думал, что Observer будет уведомлено, когда bookRep.getBookLiveData() закончится и будет получено значение. Спасибо за вашу помощь.

1 Ответ

1 голос
/ 30 апреля 2019

bookRep.getBookLiveData().getValue() всегда будет возвращать null.Поскольку вы устанавливаете значение null во ViewModel следующим образом: bookLiveData.setValue(null) в строке 7, bookLiveData всегда null при первоначальном запуске.

Вы не можете использовать getValue() для LiveData объект, чтобы получить значение здесь, потому что это всегда нуль при инициализации.Вам необходимо соблюдать , чтобы получать уведомления, когда оно действительно выдает значение.

Существует несколько различных способов его решения.Одним из способов является наблюдение getBookLiveData() в ViewModel с использованием метода observeForever().

private LiveData<Book> bookFromRep;
private MutableLiveData<Book> bookLiveData = new MutableLiveData<>();
private Observer<Book> bookObserver = bookLiveData::postValue; // Book observer posts value to bookLiveData.

public MyViewModel(@NonNull Application application) {
    super(application);
    ...
    bookFromRep = bookRep.getBookLiveData();
    bookFromRep.observeForever(bookObserver);
    ....
}

@Override
protected void onCleared() {
    super.onCleared();

    // Don't forget to remove observer when you use observeForever()
    bookFromRep.removeObserver(bookObserver);
}

Другой, и, возможно, лучший, подход к этой проблеме заключается в использовании MediatorLiveData .Я не буду включать его реализацию здесь, но я рекомендую понять различные подходы и найти лучший подход, который соответствует вашим потребностям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...