调用getValue()后,LiveData对象保持为空

rom*_*eso 6 android-mvvm android-room android-livedata

我想在LiveData对象上的存储库中更新对象的成员变量。问题是,如果我调用了getValue()方法,尽管该值确实存在于我的RoomLibrary中,但我仍会收到NullPointerException。

我现在的问题是,如何从LiveData对象获取值,而无需调用observe()方法?(我无法在我的存储库中调用观察方法,因为该方法要我输入LifeCycleOwner-引用,该引用在我的存储库中不存在)。

有什么方法可以从LiveData对象中获取值?

我的架构如下所示:ViewModel->存储库-> Dao

adi*_*e49 5

您需要在 ViewModel 中初始化 LiveData 对象,然后再像这样在 Activity/Fragment 中观察它

产品视图模型.java

public ProductViewModel(DataRepository repository, int productId) {
    mObservableProduct = repository.loadProduct(mProductId);
}
public LiveData<ProductEntity> getObservableProduct() {
    return mObservableProduct;
}
Run Code Online (Sandbox Code Playgroud)

这里 observableProduct 是用于观察产品详细信息的 LiveData,它在构造函数中初始化并使用 getObservableProduct() 方法获取

然后你可以像这样观察Activity/Fragment中的LiveData

MainActivity.java

productViewModel.getObservableProduct().observe(this, new Observer<ProductEntity>() {
    @Override
    public void onChanged(@Nullable ProductEntity productEntity) {
        mProduct = productEntity;
    }
});
Run Code Online (Sandbox Code Playgroud)

由于您已经设置了代码架构,例如 LiveData 的 Flow

DAO -> 存储库 -> ViewModel -> 片段

您不需要观察存储库中的 LiveData,因为您无法从那里更新 UI。相反,从 Activity 观察它并从那里更新 UI。

正如您所说,它在 getValue() 上给出 null,请确保您正在更新数据库并从 DAO 的单个实例获取数据库,就像我使用 DAO 一样,它不会通知使用 LiveData 将一个 DAO 实例的数据库更新为第二个 DAO 实例

您也可以按照@Martin Ohlin 的建议观察Forever,但它不会感知生命周期,并可能导致崩溃。在永久观察之前先检查您的要求

请参阅此了解完整的 LiveData 流程

有关DAO 问题请参阅此

编辑 1 - 不使用 LifecycleOwner

您可以使用void observeForever (Observer<T> observer)参考)方法来观察 LiveData,而无需LifecycleOwner像我在上面的示例中使用此上下文提供的那样提供任何内容。

这是您在不提供任何 LifecycleOwner 的情况下观察 LiveData 并观察存储库本身中的 LiveData 的方式

private void observeForeverProducts() {
    mDatabase.productDao().loadAllProducts().observeForever(new Observer<List<ProductEntity>>() {
        @Override
        public void onChanged(@Nullable List<ProductEntity> productEntities) {
                Log.d(TAG, "onChanged: " + productEntities);
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

但是您需要removeObserver(Observer)显式调用以停止观察 LiveData,这在之前的情况下是使用 LifecycleOwner 自动完成的。所以根据文档

您应该手动调用removeObserver(Observer)停止观察此LiveData。虽然 LiveData 有这样的观察者之一,但它将被视为活动的。

由于这不需要 LifecycleOwner 您可以在存储库中调用它,而无需使用提到的存储库中缺少的参数


Mar*_*lin 0

我不确定你到底想在这里完成什么,但如果你使用 observeForever而不是observe,则可以在没有LifeCycleOwner的情况下进行观察。