【问题标题】:MutableLiveData does not notify observerMutableLiveData 不通知观察者
【发布时间】:2019-09-18 19:14:45
【问题描述】:

我正在尝试将MutableLiveData 与数据库中的预填充值一起使用,但Observer 总是将null 作为book 返回。我需要将其保留为MutableLiveData,而不是LiveData,因为我必须在某些地方以编程方式设置它。因此,我使用从数据库中检索到的LiveData 调用setValue。代码:

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】:

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

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

    有几种不同的方法可以解决它。一种方法是使用observeForever() 方法在ViewModel 中观察getBookLiveData()

    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。我不会在这里介绍它的实现,但我建议您了解不同的方法并找到适合您需要的最佳方法。

    【讨论】:

    • 谢谢,我用MediarorLiveData的方式如下:bookLiveData = new MediatorLiveData&lt;&gt;(); bookLiveData.addSource(bookRep.getBookLiveData(), b -&gt; bookLiveData.setValue(b));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多