Android空指针异常求助:调用UserData.getErrorCode()时对象为空
问题排查与修复方案
核心问题分析
assert语句无效:Android发布版默认会禁用assert,你添加的assert result != null;在用户的正式App中完全不会执行,等于没加任何空判断,这是崩溃仍发生的直接原因。- 真实崩溃根源:崩溃日志显示
UserData.getErrorCode()空指针,说明你的FetchQuiz对象本身不为null,但它内部持有的UserData字段是null,而FetchQuiz.getErrorCode()方法内部直接调用了userData.getErrorCode(),最终触发空指针。你之前只判断了result不为null,没检查其内部的UserData。
修复后的代码示例
private void getLatestQuiz(){ Call<FetchQuiz> fetchLatestQuizCall = ApiController.getInstance().getApi().getLatestQuiz(); fetchLatestQuizCall.enqueue(new Callback<FetchQuiz>() { @Override public void onResponse(Call<FetchQuiz> call, Response<FetchQuiz> response) { // 先判断HTTP请求是否成功,避免无效body if (!response.isSuccessful()) { handleQuizLoadFailure(); Log.d(TAG,"fetchLatestQuizCall HTTP错误码: "+response.code()); return; } FetchQuiz result = response.body(); // 真实生效的空判断,替代assert if (result == null) { handleQuizLoadFailure(); Log.d(TAG,"fetchLatestQuizCall 响应体为空"); return; } // 检查FetchQuiz内部的UserData是否为空(崩溃的核心诱因) UserData userData = result.getUserData(); // 假设FetchQuiz有此getter方法 if (userData == null) { handleQuizLoadFailure(); Log.d(TAG,"fetchLatestQuizCall 响应中UserData为空"); return; } int errorCode = userData.getErrorCode(); String message = result.getMessage(); Log.d(TAG,"fetchLatestQuizCall 响应结果: errorCode = "+errorCode+" message = "+message); // 用常量在前的equals避免message为空时的空指针 if (errorCode == 0 && "Data fetched".equals(message)) { List<Quiz> quizList = result.getQuizList(); // 额外检查列表有效性,避免RecyclerView异常 if (quizList != null && !quizList.isEmpty()) { setLatestQuizRecyclerview(quizList, getContextNullSafety()); } else { handleQuizLoadFailure(); } } else { handleQuizLoadFailure(); } } @Override public void onFailure(Call<FetchQuiz> call, Throwable t) { handleQuizLoadFailure(); Log.d(TAG,"fetchLatestQuizCall 请求失败: "+t.getLocalizedMessage()); Log.d(Constants.ERROR_TAG,"fetchLatestQuizCall 请求失败详情: "+t.getLocalizedMessage()); } // 提取重复逻辑,减少代码冗余 private void handleQuizLoadFailure() { if (binding != null) { binding.textLatestQuiz.setVisibility(View.GONE); binding.textMore.setVisibility(View.GONE); } } }); }
关键优化点说明
- 替换
assert为实际生效的空判断,确保发布版也能生效。 - 先判断
response.isSuccessful():Retrofit在HTTP请求失败(如4xx、5xx)时会返回null body,提前拦截这类场景。 - 检查
FetchQuiz内部的UserData字段,从根源解决空指针。 - 使用
"Data fetched".equals(message):避免message为null时触发新的空指针。 - 提取失败处理逻辑到单独方法,降低代码维护成本。
内容的提问来源于stack exchange,提问作者Muhanned Khwaldeh
相关产品推荐
相关产品推荐

