如何修复读取空引用字段引发的叫车App呼叫司机崩溃问题
解决呼叫司机按钮触发的NullPointerException问题
我来帮你拆解这个崩溃问题并给出具体的修复方案:
问题根源
你遇到的NullPointerException是因为直接访问了response.body().success,但response.body()可能为null。这种情况通常发生在两种场景:
- HTTP请求未成功(比如返回4xx/5xx状态码),此时
response.isSuccessful()会返回false,response.body()必然为null - 即使请求成功,服务器也可能返回空的响应体,导致
response.body()为null
直接跳过校验访问response.body().success就会触发空指针异常。
修复步骤
1. 先校验请求状态与响应体是否非空
修改onResponse方法,先判断请求是否成功,再确保响应体不为null后再访问属性:
@Override public void onResponse(@NonNull Call<FCMResponse> call, Response<FCMResponse> response) { // 先检查HTTP请求是否成功(状态码为2xx) if (response.isSuccessful()) { FCMResponse fcmResponse = response.body(); // 确保响应体不为null再访问字段 if (fcmResponse != null) { // 注意:原代码逻辑好像搞反了?success==1应该代表请求成功吧?建议核对字段定义 if (fcmResponse.success == 1) { Toast.makeText(Home.this, "Request Sent!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(Home.this, "Request Failed!", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(Home.this, "Empty response from server!", Toast.LENGTH_SHORT).show(); } } else { // 处理请求失败的情况,提示具体状态码方便排查 Toast.makeText(Home.this, "Request failed with code: " + response.code(), Toast.LENGTH_SHORT).show(); } }
2. 提前校验content对象是否非空
在调用sendMessage之前,要确保content不为null(因为token可能查询不到),避免后续请求出错:
if (content != null) { mService.sendMessage(content) .enqueue(new Callback<FCMResponse>() { // 上面的onResponse实现 @Override public void onFailure(Call<FCMResponse> call, Throwable t) { // 别忘了实现onFailure,处理网络请求失败的情况 Toast.makeText(Home.this, "Failed to send request: " + t.getMessage(), Toast.LENGTH_SHORT).show(); } }); } else { Toast.makeText(Home.this, "Could not get driver's notification token!", Toast.LENGTH_SHORT).show(); }
3. 校验mLastLocation是否非空
创建LatLng时用到了mLastLocation,如果它为null也会触发空指针,所以在方法开头添加校验:
private void sendRequestToDriver(String driverId) { // 先检查位置信息是否可用 if (mLastLocation == null) { Toast.makeText(Home.this, "Unable to retrieve your location!", Toast.LENGTH_SHORT).show(); return; } DatabaseReference tokens = FirebaseDatabase.getInstance().getReference(Common.token_tbl); tokens.orderByKey().equalTo(driverId) .addListenerForSingleValueEvent(new ValueEventListener() { // 原有的onDataChange和onCancelled实现 }); }
额外建议
- 一定要实现
onFailure方法,处理网络请求失败(比如无网络、服务器超时)的情况,避免静默崩溃 - 调试时可以通过Log打印
response.code()和response.errorBody(),排查服务器返回的具体错误信息
内容的提问来源于stack exchange,提问作者Joy Dey
相关产品推荐
相关产品推荐

