You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android使用Retrofit获取OpenWeather数据存入MutableLiveData后为空如何解决

根因分析

你遇到的空指针是异步请求时序问题导致的:

  • Retrofit的call.enqueue()是异步网络请求,会在后台线程执行,不会阻塞当前主线程
  • 你在调用callWeatherAPI()之后立刻执行Log.i(TAG,data.getValue().toString()),此时网络请求还没完成,data作为新创建的MutableLiveData还没有被赋值,getValue()返回null,调用toString()就触发了空指针
    你在onResponse里能打印出数据,是因为那时候网络请求已经成功返回,才给data完成赋值,代码实际执行顺序和你写代码的顺序不一致。
解决方案

1. 移除/移动即时读取LiveData值的代码

把getWeather方法里的错误日志行删掉,或者移到onResponse里,只有请求成功后再读取data的值:

public MutableLiveData<OpenWeather> getWeather() {
    retrofit = new RetrofitService().getRetroInstance(BASE_URL);
    opwAPI = retrofit.create(OpenWeatherAPI.class);
    data = new MutableLiveData<OpenWeather>();
    callWeatherAPI();
    // 删除这行错误代码 Log.i(TAG,data.getValue().toString());
    return data;
}

// onResponse里可以正常打印
@Override
public void onResponse(Call<OpenWeather> call, Response<OpenWeather> response) {
    OpenWeather temp = response.body();
    Log.i(TAG,"API CONNECT SUCCESS");
    if(temp != null){
        Log.i(TAG,temp.toString());
        data.setValue(temp);
        // 这里读取data值就不会为空
        Log.i(TAG, "请求成功后data值:"+ data.getValue().toString());
    }
}

2. 遵循LiveData观察者模式使用

不要直接调用data.getValue()来获取值,在ViewModel或Activity层通过observe方法监听LiveData的变化,只有数据更新后才会触发回调,此时数据一定非空:
举个在Activity中观察的示例:

// MainActivity的onCreate里
mainActivityViewModel.getWeatherLiveData().observe(this, openWeather -> {
    // 这里只有当data赋值成功后才会执行,openWeather非空,直接用就行
    Log.i("MainActivity", "获取到天气数据:"+openWeather.toString());
    // 更新UI等操作都写在这里
});

3. 可选防护措施

如果有必须直接读取LiveData值的场景,先做空判断,避免空指针:

if(data.getValue() != null){
    Log.i(TAG,data.getValue().toString());
}

内容的提问来源于stack exchange,提问作者codingRookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 06:36:01