Retrofit缓存为空时触发NullPointerException问题求助
修复首次无网络时的NullPointerException问题
很明显你遇到的问题出在首次无网络访问时缓存为空的场景:此时OkHttp返回的响应没有body,你后续用null状态的kk去创建ArrayList,触发了null对象调用toArray()的NPE。我们一步步来修复:
1. 先处理响应成功的判断
当使用only-if-cached但没有缓存时,OkHttp会返回504的HTTP错误,这时候onResponse依然会被调用(而非onFailure),但response.isSuccessful()会是false,response.body()也为null。所以第一步要先判断响应是否有效:
@Override public void onResponse(@NonNull Call<Responce> call, @NonNull Response<Responce> response) { progressBarTrain.setVisibility(View.INVISIBLE); // 先拦截响应失败的情况(包括无缓存的无网络场景) if (!response.isSuccessful()) { textError(); return; } // ... 后续处理逻辑 }
2. 避免集合对象为null
即使响应body不为null,接口返回的products字段也可能是null。所以要给集合兜底一个空值,避免后续创建ArrayList时出错:
// 安全获取products,兜底空集合 List<Responce.Item> products = new ArrayList<>(); if (response.body() != null && response.body().products != null) { products = response.body().products; }
3. 安全初始化ArrayList
现在用兜底后的集合去创建ArrayList,就不会触发NPE了。整合后的完整onResponse方法如下:
@SuppressLint("SetTextI18n") @Override public void onResponse(@NonNull Call<Responce> call, @NonNull Response<Responce> response) { progressBarTrain.setVisibility(View.INVISIBLE); // 处理响应失败(无缓存/HTTP错误) if (!response.isSuccessful()) { textError(); return; } // 安全获取products集合 List<Responce.Item> products = new ArrayList<>(); if (response.body() != null && response.body().products != null) { products = response.body().products; } // 创建适配器并绑定 adapter = new DetailTrainAdapter(new ArrayList<>(products)); recyclerView.setAdapter(adapter); Log.d(TAG, String.valueOf(response.body())); textError.setVisibility(TextView.INVISIBLE); textErrorRestart.setVisibility(TextView.INVISIBLE); }
额外优化建议
- 可以在Interceptor中添加日志,方便调试缓存策略是否生效:
Log.d(TAG, "当前请求缓存策略: " + request.header("Cache-Control"));
- 确保
NetworkUtils.isNetworkAvailable的实现可靠,避免误判网络状态导致缓存策略失效。
内容的提问来源于stack exchange,提问作者Романыч
相关产品推荐
相关产品推荐

