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

Android Retrofit请求回调触发toArray()空指针异常排查

问题根因

这个空指针崩溃没有特殊逻辑陷阱,本质是待调用toArray()方法的集合对象实际为null,结合你提到新增功能后才出现问题的背景,触发原因基本逃不过这几类:

  • 修改数据实体类时调整了集合字段的映射规则,比如改了@SerializedName的匹配值、调整了泛型声明,导致JSON解析时列表字段匹配失败,直接被赋值为null;之前功能正常是因为字段映射完全匹配,全量数据接口永远返回数组结构
  • 新增搜索、饼图统计逻辑时,把之前写的前置判空逻辑删除或挪到了调用逻辑后面,拿到响应数据没做校验就直接传给列表、饼图组件处理
  • 新增国家筛选功能后,请求会携带特定国家标识参数,当接口查不到对应国家的统计数据时,不会返回空数组[],而是直接将列表字段返回为null,之前测试全量数据时没有覆盖到这个边界场景
  • 漏写Retrofit响应体本身的空判断,部分异常响应码场景下response.body()本身就是null,链式调用取内部列表字段自然拿到null值
修复步骤
  1. 先堵上直接崩溃点:所有集合类型变量调用类方法前,必须做空判断,用空集合做兜底,永远不要让集合变量在业务流程里持有null值
    你第83行触发崩溃的代码大概率长这样:
    // 错误写法:无判空直接调用集合方法
    List<CovidCountry> countryList = response.body().getCountryData();
    // 给饼图塞数据时直接调用toArray,countryList为null就会触发崩溃
    pieChart.applyData(countryList.toArray());
    adapter.submitList(countryList);
    
    改成带兜底校验的写法:
    // 先校验Retrofit响应本身是否合法
    if (!response.isSuccessful() || response.body() == null) {
        showErrorTip();
        return;
    }
    List<CovidCountry> countryList = response.body().getCountryData();
    // 集合空值兜底
    if (countryList == null) {
        countryList = new ArrayList<>();
    }
    // 此时countryList永远非空,调用任何集合类方法都不会触发NPE
    pieChart.applyData(countryList.toArray());
    adapter.submitList(countryList);
    
  2. 从数据层彻底避免空集合问题:给所有实体类里的集合字段设置默认空值,JSON解析时如果对应字段不存在/返回null,会自动保留你设置的空列表,从根源上杜绝集合字段为null的情况
    写法示例:
    public class CovidApiResponse {
        // 直接初始化空列表,不需要额外判空
        private List<CovidCountry> countryData = new ArrayList<>();
        private int globalConfirmCount;
        // 其余业务字段正常声明即可
    }
    
  3. 补全边界场景测试:专门验证搜索不存在的国家名、选择无公开数据的小众国家、网络异常返回错误响应这几个场景,确认空状态下不会崩溃,能正常展示空页面提示即可。
快速排查技巧

直接在MainActivity第83行打debug断点,触发崩溃前查看栈内的变量值,10秒就能确认到底是response.body()为null,还是body内部的列表字段为null,对应调整判空逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:09:10