尝试调用空对象引用上的'void android.arch.lifecycle.LiveData.observe'虚拟方法

17

我遇到了以下错误:

我正在使用Android架构组件,尝试实例化ViewModel并从LiveData观察数据。但是我卡在这里,请帮助我解决这个问题:

Attempt to invoke virtual method 'void android.arch.lifecycle.LiveData.observe(android.arch.lifecycle.LifecycleOwner, android.arch.lifecycle.Observer)' on a null object reference

我的Fragment是这样的: 当调用getCompany()方法时,我会遇到空指针异常错误。
    public class CompanyFragment extends LifecycleFragment {
    private CompanyViewModel companyViewModel;

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        companyViewModel = ViewModelProviders.of(this).get(CompanyViewModel.class);
        companyViewModel.initData();
        companyViewModel.getCompany().observe(this, new Observer<CompanyEntity>() {
            @Override
            public void onChanged(@Nullable CompanyEntity companyEntity) {

            }
        });
    }
    @Override
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_company, container, false);
    }
}

我的ViewModel类是这样的:
public class CompanyViewModel extends ViewModel {
    private LiveData<CompanyEntity> companyEntityLiveData;
    private CompanyRepository companyRepo;

    public CompanyViewModel() {}

    public CompanyViewModel(CompanyRepository companyRepo){
        this.companyRepo = companyRepo;
    }

    public void initData(){
        companyEntityLiveData = companyRepo.getCompany();
    }

    public LiveData<CompanyEntity> getCompany() {
        return companyEntityLiveData;
    }

}

错误出现在这一行:

   companyViewModel.getCompany().observe(this, new Observer<CompanyEntity>() {
        @Override
        public void onChanged(@Nullable CompanyEntity companyEntity) {

        }
    });

这是我的CompanyRepository类:
public class CompanyRepository {
private WebService webService;

    public CompanyRepository(){

    }

    public LiveData<CompanyEntity> getCompany() {
        final MutableLiveData<CompanyEntity> data = new MutableLiveData<>();

        webService.getCompany().enqueue(new Callback<CompanyEntity>() {
            @Override
            public void onResponse(Call<CompanyEntity> call, Response<CompanyEntity> response) {
                data.setValue(response.body());
            }

            @Override
            public void onFailure(Call<CompanyEntity> call, Throwable t) {

            }
        });

        return data;
    }
}

怎么修复它!!你能帮我吗? - Praveen Cool
“你能帮我吗?”--我们没有companyRepo.getCompany()的代码,因此不知道为什么它可能会返回null。您可以编辑您的问题并发布CompanyRepository的代码。 - CommonsWare
请提供需要翻译的英文内容。 - Praveen Cool
我无法解释你为什么会遇到这个崩溃。我能提供的最好建议就是在你的视图模型中逐步执行 initData()getCompany() 调用,看看发生了什么。 - CommonsWare
请检查initData()函数内companyRepo.getCompany()返回值是否为非空。 - Alex
显示剩余2条评论
6个回答

10

您必须观察 LiveData 的同一实例。在 CompanyRepository 类中,每次访问公司时,您都会创建一个新的 LiveData 实例,这意味着您的活动随后会观察旧实例。

getCompany 方法应该更改为始终返回 LiveData 的相同实例。此外,由于您正在尝试在后台线程上更新值,因此应将 setValue() 更改为 postValue()。

final MutableLiveData<CompanyEntity> data = new MutableLiveData<>();
public LiveData<CompanyEntity> getCompany() {

    webService.getCompany().enqueue(new Callback<CompanyEntity>() {
        @Override
        public void onResponse(Call<CompanyEntity> call, Response<CompanyEntity> response) {
            data.postValue(response.body());
        }

        @Override
        public void onFailure(Call<CompanyEntity> call, Throwable t) {

        }
    });

    return data;
}

4
也许你可以在方法后声明一个LiveData对象。这就是我遇到的情况。
fun aMethod() {
    _aLiveData.value = Unit
}

private val _aLiveData = MutableLiveData<Unit>()
val aLiveData: LiveData<Unit> = _aLiveData

实际上,它应该是这样的。
private val _aLiveData = MutableLiveData<Unit>()
val aLiveData: LiveData<Unit> = _aLiveData

fun aMethod() {
    _aLiveData.value = Unit
}

1

改变

public CompanyViewModel(){
    companyRepo= new companyRepo();
}

public LiveData<CompanyEntity> getCompany() {
    if(companyEntityLiveData==null)
        companyEntityLiveData= companyRepo.getSection();
    return companyEntityLiveData;
}

在你的Fragment中:
    CompanyViewModel companyViewModel= 
    ViewModelProviders.of(this).get(CompanyViewModel .class);
    LiveData<CompanyEntity> s = companyViewModel.getCompany();

    s.observe(this, new Observer<CompanyEntity>() {
        @Override
        public void onChanged(@Nullable CompanyEntity companyEntity) {
            Toast.makeText(getContext(),"Go go go", Toast.LENGTH_LONG).show();
        }
    });

4
为了帮助以后可能遇到略有不同的问题的访问者更好地理解您的答案,请为您的答案添加一些上下文。 - Ruzihm

0
companyRepo.getCompany() 返回 null,显然。
这对我来说是有效的。

回答目前的表述不清楚。请编辑以添加更多细节,帮助他人理解如何解决所提出的问题。您可以在帮助中心找到有关撰写良好答案的更多信息。 - moken

0
在getCompany方法中,你需要检查companyEntityLiveData对象是否为null,如果是,则调用其中的服务。
public LiveData<CompanyEntity> getCompany() {
    if(companyEntityLiveData == null){
       companyEntityLiveData = companyRepo.getCompany();
    }
    return companyEntityLiveData;
}

0
问题在于您试图使用尚未初始化的内容。因此,为了不依赖执行顺序,我们必须在存储仓库返回内容的变量中建立安全的可空性。
通过这样做,即使在仓库加载属性之前,我们也可以使用该属性。请查看以下示例中的执行顺序:
val aUse: LiveData<T> = MediatorLiveData<T>().apply {
    nullableObj?.let {
    }
}
private val nullableObj: LiveData<T2>? = repository::getNullableObj

在使用 Repository #getCompany() 之前,请检查其是否为空。在 Kotlin 中可以这样写:
companyVM.company?.observe(...) { ... }

GL


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接