开发实时货币转换APP遭遇java.lang.NullPointerException求助
修复货币转换APP的NullPointerException问题
问题根源
崩溃的直接原因是response.body()返回了null,导致你调用res.getAsJsonObject("rates")时触发空指针异常。这种情况通常发生在API请求未返回2xx成功响应(比如400参数错误、401未授权、500服务器错误),此时Retrofit不会返回响应体,response.body()自然为null。
修复步骤
你需要在代码中添加多层空值校验,同时处理各类异常场景:
- 先校验请求是否成功:通过
response.isSuccessful()判断HTTP响应是否正常 - 校验响应体是否存在:确保
res不为null后再操作 - 校验"rates"字段是否有效:避免API返回结构不符合预期导致的空指针
- 处理用户输入的异常情况:防止空值或非数字输入触发格式转换异常
修改后的代码如下:
MoneyButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RetrofitInterface retrofitInterface = RetrofitBuilder.getRetrofitInstance().create(RetrofitInterface.class); Call<JsonObject> call = retrofitInterface.getExchangeCurrency(MoneyTo.getSelectedItem().toString()); call.enqueue(new Callback<JsonObject>() { @Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { // 1. 判断请求是否成功 if (!response.isSuccessful()) { MoneyTextView.setText("请求失败:" + response.code()); return; } JsonObject res = response.body(); // 2. 校验响应体是否为空 if (res == null) { MoneyTextView.setText("未获取到数据"); return; } // 3. 校验"rates"字段是否存在且为JsonObject类型 if (!res.has("rates") || !res.get("rates").isJsonObject()) { MoneyTextView.setText("数据格式错误"); return; } JsonObject rates = res.getAsJsonObject("rates"); // 4. 处理用户输入的金额 String inputStr = MoneyEd.getText().toString().trim(); if (inputStr.isEmpty()) { MoneyTextView.setText("请输入金额"); return; } double currency; try { currency = Double.parseDouble(inputStr); } catch (NumberFormatException e) { MoneyTextView.setText("请输入有效的数字"); return; } // 5. 校验目标货币汇率是否存在 String targetCurrency = MoneyFrom.getSelectedItem().toString(); if (!rates.has(targetCurrency) || !rates.get(targetCurrency).isJsonPrimitive()) { MoneyTextView.setText("不支持该货币转换"); return; } double multiplier = rates.get(targetCurrency).getAsDouble(); double result = currency * multiplier; MoneyTextView.setText(String.format("%.2f", result)); // 格式化保留两位小数更友好 } @Override public void onFailure(Call<JsonObject> call, Throwable t) { // 不要空实现,处理网络失败场景 MoneyTextView.setText("网络连接失败"); t.printStackTrace(); // 调试时打印异常,发布版可移除 } }); } });
额外建议
- 调试时可以打印
response.code()和response.errorBody().string(),查看API返回的具体错误信息(比如参数是否正确、API密钥是否有效) - 给Spinner设置默认选中项,避免
MoneyTo.getSelectedItem()返回null - 优先使用
Double.parseDouble()配合try-catch,比直接用Double.valueOf()更安全
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

