当前位置: 首页 > 知识库问答 >
问题:

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

申屠项明
2023-03-14

我想在LiveData-Object上更新存储库中对象的成员变量。问题是,如果我调用getValue()方法,我总是会得到一个NullPointerExctive,尽管这个值确实存在于我的房间库中。

我现在的问题是,如何在不调用observe()方法的情况下从LiveData对象获取值?(我无法在我的存储库中调用observe方法,因为该方法希望我输入一个LifeCycleOwner-reference,它不在我的存储库中)。

有没有办法从LiveData-对象中获取值?

我的架构是这样的:ViewModel--

共有3个答案

左丘宜年
2023-03-14

我不确定你到底想在这里完成什么,但是如果你使用观察永远而不是观察,没有生命周期所有者也可以观察。

韩自怡
2023-03-14

为了让LiveData对象正常工作,您需要使用observe方法。也就是说,如果您想要使用getValue()方法,并且希望得到非null响应,那么需要使用observe方法。确保在ViewModel中初始化LiveData对象,正如@adityakamble49在他的回答中所说的那样。要初始化对象,可以传递在存储库中创建的LiveData对象的引用:

ViewModel。JAVA

private LiveData<Client> clientLiveData;
private ClientRepository clientRepo;
public ViewModel(ClientRepository clientRepo) {
    this.clientRepo = clientRepo;
    clientLiveData = clientRepo.getData();
}

然后,您必须从活动中观察ViewModel,并调用要在ViewModel(或Repo)中更新的方法,但请记住,Repo与ViewModel和ViewModel与UI有关:https://developer.android.com/jetpack/docs/guide ):

一个ctivity.java

viewModel.getClient().observe(this, new Observer<Client>() {
        @Override
        public void onChanged(@Nullable Client client) {
            viewModel.methodWantedInViewModel(client);
        }
    });

我希望它能有所帮助。

荣俊杰
2023-03-14

在像这样的活动/片段中观察LiveData对象之前,需要在ViewModel中初始化它

ProductViewModel。JAVA

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

这里可观察的产品是LiveData,用于观察产品细节,该细节在构造函数中初始化,并使用get观察产品()方法获取

然后你可以像这样观察活动/片段中的LiveData

主要活动。JAVA

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

由于您已经设置了LiveData流这样的代码体系结构

刀-

您不需要观察存储库中的LiveData,因为您无法从那里更新UI。而是从活动中观察,并从活动中更新UI。

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

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

有关完整的LiveData流,请参阅此

有关DAO问题,请参阅此

编辑1-不使用LifecycleOwner

您可以使用void observeForever(观察者

这就是在不提供任何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);
            }
        });
    }

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

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

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

 类似资料:
  • 在viewmodel类中获取数据方法

  • 我试图抛出一个目标。但是在运行时,对象类仍然是一个派生类。 那么为什么类属性没有改变呢?

  • 我通过在方法之外添加一个简单的Ride实例来测试它,它工作得很好。 我还尝试将监听器更改为,结果相同。 Edit2:当我试图从数据库中检索整数时,我会得到一条错误消息。

  • 我知道以前有人问过很多这个问题,但在我的情况下,我找不到解决办法。我请求获得关于POJO(电影)列表的json回复 虽然这是我第一次使用改型,但我在标题中遇到了问题。我正在创建的url是正确的,下面是响应的示例: 这是我的模特 } 我的@GET 我的数据请求类 最后,我想在我的主要活动中做些什么

  • 我收到了一个要求,在新的一个月开始时强制重新授权用户(我们有一个月订阅模式)。为了实现这一点,并且不影响应用程序中使用的其他身份验证提供者,我修改了登录调用,如下所示: 以前: 之后: 请注意,出于测试目的,< code > expire suc 将被设置为1分钟;一旦实施成功,它将被计算到月底。 我期望我们的身份(扩展)在到达后会获得其属性 false,但事实并非如此。正在读取ClaimsIde

  • 问题内容: 我创建了一个这样的对象: 我想保存该对象。我怎样才能做到这一点? 问题答案: 你可以使用标准库中的模块。这是你的示例的基本应用: 你还可以定义自己的简单实用程序,如下所示,该实用程序打开文件并向其中写入单个对象: 更新资料 由于这是一个非常受欢迎的答案,因此,我想谈谈一些高级用法主题。 实际使用该cPickle模块几乎总是可取的,而不是因为该模块是用C编写的并且速度更快。它们之间有一些