MutableLiveData不会通知观察者

时间:2019-04-30 07:09:55

标签: viewmodel observer-pattern android-livedata mutablelivedata

我正在尝试将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为null吗?我认为Observer完成并获取值后会通知bookRep.getBookLiveData()。感谢您的帮助。

1 个答案:

答案 0 :(得分: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。我将不在这里介绍其实现,但我建议您了解不同的方法并找到适合您需求的最佳方法。