使用Retrofit获取统计数据后设置TextView报NullPointerException问题咨询
解决Retrofit异步请求导致的NullPointerException问题
你碰到的这个空指针问题其实很典型——核心原因就是Retrofit的网络请求是异步执行的,你的代码执行顺序踩了异步请求的坑:
问题根源分析
看你的代码流程:
- 调用
init()方法,里面先执行getStatistics()发起网络请求,但这个请求是异步的,方法会立刻返回,不会等网络响应回来。 - 紧接着你就执行
txtNrCompleted.setText(String.format("%s", statistics.getTask())),这时候statistics对象还没被赋值!因为onResponse回调还没触发,setStatistics()根本没执行过,statistics还是null,自然会抛出Attempt to invoke virtual method... on a null object reference的异常。
修复方案
这里给你两种靠谱的修复思路:
1. 把UI更新逻辑移到数据准备好之后
最简单的方式是把设置TextView的代码放到setStatistics()方法里,确保只有当statistics被成功赋值后才更新UI:
public void setStatistics(STATISTIC statistics){ this.statistics = statistics; // 先做双重空值判断,避免意外 if(statistics != null && txtNrCompleted != null){ txtNrCompleted.setText(String.format("%s", statistics.getTaskComplet())); } }
或者直接在onResponse回调里处理UI更新:
@Override public void onResponse(Call<STATISTIC> call, Response<STATISTIC> response) { if(response.isSuccessful() && response.body() != null) { setStatistics(response.body()); // 直接在这里更新UI,确保数据已就绪 txtNrCompleted.setText(String.format("%s", response.body().getTaskComplet())); }else{ Log.d("STATISTICS", "Error: " + response.code()); } }
2. 初始化时设置默认值,避免空白或异常
在init()里先给TextView设置一个默认提示,等请求完成后再替换成真实数据:
public void init() { // 先设置加载提示,提升用户体验 txtNrCompleted.setText("加载中..."); getStatistics(); }
额外注意事项
- 别忘了确认
txtNrCompleted已经通过findViewById完成初始化,避免UI控件本身为null导致的空指针。 - Retrofit的
onResponse和onFailure回调默认是在主线程执行的,所以直接在里面更新UI没问题;如果后续自己扩展了线程逻辑,记得用runOnUiThread()切换回主线程更新UI。
内容的提问来源于stack exchange,提问作者8kk
相关产品推荐
相关产品推荐

