Retrofit2调用API报空对象引用NullPointerException致APP崩溃
问题分析
报错的核心原因是TimTroApi对象为null:TimTroApi是你定义的Retrofit接口,本身没有静态方法,你直接通过类名调用TimTroApi.getdatanewPost()本质是在一个未初始化的空引用上调用方法,必然触发空指针。
Postman调通接口仅能证明服务端逻辑正常,这个崩溃是客户端没有正确初始化Retrofit接口实例导致的,和接口返回数据无关。
修复方案
按以下步骤修改代码即可解决:
- 在
HomeFragment中声明TimTroApi的成员变量,不要直接用接口类名调用方法
// 声明Api实例成员变量 private TimTroApi timTroApi; // 替换为你自己的接口根地址,注意必须以/结尾 private static final String BASE_URL = "https://你的实际接口域名/";
- 在Fragment的初始化生命周期(
onCreate/onViewCreated都可以)中,通过ApiClient生成Retrofit实例后,创建TimTroApi的实现类对象
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 初始化Api接口实例,这一步是你之前完全漏掉的 timTroApi = ApiClient.getClient(BASE_URL).create(TimTroApi.class); // 其余原有初始化逻辑,比如swipeContainer的绑定等 // ... loadDataNewPost(); }
- 修改
loadDataNewPost方法中的调用逻辑,使用初始化完成的实例调用接口方法
private void loadDataNewPost() { // 替换原来的TimTroApi.getdatanewPost(),用实例调用 timTroApi.getdatanewPost().enqueue(new Callback<List<Post>>() { @Override public void onResponse(Call<List<Post>> call, Response<List<Post>> response) { swipeContainer.setRefreshing(false); if (response.isSuccessful() && response.body() != null) { postArrayList = (ArrayList<Post>) response.body(); getDataNewPost(postArrayList); } else { Log.e("api_error", "接口返回异常,状态码:" + response.code()); } } @Override public void onFailure(Call<List<Post>> call, Throwable t) { Log.e("aaa", t.getMessage()); swipeContainer.setRefreshing(false); } }); }
额外避坑提示
- 你当前的
ApiClient单例写法有隐患:如果后续传入不同的url调用getClient,因为已经判断retrofit != null,会直接返回第一次初始化的实例,导致baseUrl错误。如果你的应用只有一个固定接口根地址,建议直接把baseUrl写在ApiClient内部,不要对外暴露传参的入口。 - Retrofit的baseUrl必须以
/结尾,@POST注解里的接口路径不要以/开头,否则会出现路径拼接错误。 - 解析返回值的时候最好加
response.body() != null的判断,避免服务端返回空数据的时候触发类型转换空指针。
内容的提问来源于stack exchange,提问作者tomm1
相关产品推荐
相关产品推荐

