MutableLiveData不通知观察者

问题描述 投票:1回答:1

我试图使用MutableLiveData与数据库预先填充的值,但Observer总是返回null作为book。我需要保持它为MutableLiveData,而不是LiveData,因为我必须在某些地方以编程方式设置它。因此,我用从DB检索到的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()。谢谢您的帮助。

viewmodel observer-pattern android-livedata mutablelivedata
1个回答
1
投票

bookRep.getBookLiveData().getValue()将永远返回null。由于您在ViewModel中设置null值,如下所示:bookLiveData.setValue(null)在第7行,bookLiveData在首次启动时始终为null

您不能在getValue()对象上使用LiveData来获取值,因为它在初始化时始终为null。您需要观察,以便在实际发出值时收到通知。

有几种不同的方法可以解决它。一种方法是使用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。我不会在此处包含其实现,但我建议理解不同的方法并找到最适合您需求的方法。

© www.soinside.com 2019 - 2024. All rights reserved.