Android开发遇NullPointerException:调用null对象方法崩溃求助
问题描述
我正在开发一款扫描商品条码并获取信息的应用,使用Retrofit与API通信。扫描数据库中不存在的商品时应用崩溃,崩溃日志如下:
E/an.fifthscanne: [qarth_debug:] get PatchStore::createDisableExceptionQarthFile method fail. E/AndroidRuntime: FATAL EXCEPTION: main Process: com.givaudan.fifthscanner, PID: 9635 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.givaudan.fifthscanner.http.Product.getBrand()' on a null object reference at com.givaudan.fifthscanner.form$2.onResponse(form.java:121)
崩溃发生在这行代码:
brand = data.getProductField().getBrand() + "\n";
尝试添加空值判断的错误处理逻辑但未成功,也无法直接照搬初始化对象的方案,相关代码如下:
public class form extends AppCompatActivity { private TextView textViewResult; private TextView success; ProgressDialog progressDialog; Button btnInsert; String brand; String barcode; String line; String packaging; String countries; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_form); textViewResult = findViewById(R.id.text_view_result); btnInsert = findViewById(R.id.bt_send_excel); //Set the "Loading PopUp" progressDialog = new ProgressDialog(form.this); progressDialog.setMessage("Loading ..."); btnInsert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { addProductData(brand, barcode, line, packaging, countries); progressDialog.show(); } }); //retrieve value CODE_BARRE from MainActivity String productCode = getIntent().getStringExtra("productId"); //========================= Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://world.openfoodfacts.org/api/v0/produit/") .addConverterFactory(GsonConverterFactory.create()) .build(); RequestPlaceHolder requestPlaceHolder = retrofit.create(RequestPlaceHolder.class); String url = "https://world.openfoodfacts.org/api/v0/produit/" + productCode + ".json"; Call<Data> call = requestPlaceHolder.getData(url); call.enqueue(new Callback<Data>() { @Override public void onResponse(Call<Data> call, Response<Data> response) { /*if (response.body() != null) { //textViewResult.setText("Code" + response.code()); textViewResult.setText("The product does not exist with this barcode,\n" + "look for the barcode of the product on: \n\n" + "https://fr.openbeautyfacts.org/"); return; }*/ if (response.isSuccessful()) { //Retrieve data and display it Data data = response.body(); barcode = productCode + "\n"; brand = data.getProductField().getBrand() + "\n"; line = data.getProductField().getLine() + "\n"; packaging = data.getProductField().getPackaging() + "\n"; countries = data.getProductField().getCountries() + "\n"; String content = brand + "\n" + barcode + "\n" + line + "\n" + packaging + "\n" + countries; textViewResult.append(content); } } @Override public void onFailure(Call<Data> call, Throwable t) { textViewResult.setText(t.getMessage()); } }); } //Add data to excel public void addProductData(String brand, String barcode, String line, String packaging, String countries) { StringRequest stringRequest = new StringRequest(Request.Method.POST, "https://script.google.com/macros/s/AKfycbwyXLOJEa_Bvgb4Ae-qqX5zWQO0E_MJcUPy7nJBft9MTq3BvCd6gcwy0_2MhGUDFZNo8w/exec", new com.android.volley.Response.Listener<String>() { @Override public void onResponse(String response) { Intent intent = new Intent(form.this, SuccessActivity.class); startActivity(intent); progressDialog.hide(); } }, error -> { }) { @Override protected Map<String, String> getParams() { Map<String, String> params = new HashMap<>(); params.put("sbrand", brand); params.put("sbarcode", barcode); params.put("sline", line); params.put("spackaging", packaging); params.put("scountries", countries); return params; } }; int socketTimeOut = 50000; RetryPolicy retryPolicy = new DefaultRetryPolicy(socketTimeOut, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); stringRequest.setRetryPolicy(retryPolicy); RequestQueue requestQueue = Volley.newRequestQueue(this); requestQueue.add(stringRequest); } }
解决方案
逐层添加空值校验
当商品不存在时,API会返回200成功响应,但response.body()内的productField为null。需要在获取数据前逐层判断空值,同时对单个字段做空值兜底:@Override public void onResponse(Call<Data> call, Response<Data> response) { if (response.isSuccessful()) { Data data = response.body(); // 校验Data对象是否为空 if (data == null) { textViewResult.setText("未找到该商品信息"); return; } // 校验Product对象是否为空 Product product = data.getProductField(); if (product == null) { textViewResult.setText("未找到该商品信息"); return; } // 对每个字段做空值兜底,避免拼接时出现空指针 barcode = productCode + "\n"; brand = (product.getBrand() != null ? product.getBrand() : "无品牌") + "\n"; line = (product.getLine() != null ? product.getLine() : "无产品线") + "\n"; packaging = (product.getPackaging() != null ? product.getPackaging() : "无包装信息") + "\n"; countries = (product.getCountries() != null ? product.getCountries() : "无销售国家") + "\n"; String content = brand + "\n" + barcode + "\n" + line + "\n" + packaging + "\n" + countries; textViewResult.append(content); } else { // 处理非200的异常响应 textViewResult.setText("请求失败:" + response.code()); } }移除错误的判断逻辑
你注释掉的if (response.body() != null)逻辑不符合API返回规则,直接删除即可。优化按钮点击逻辑
防止用户在未获取商品信息时提交空数据,添加状态判断:btnInsert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (barcode == null || barcode.isEmpty()) { textViewResult.setText("请先获取商品信息"); return; } addProductData(brand, barcode, line, packaging, countries); progressDialog.show(); } });
内容的提问来源于stack exchange,提问作者LAZREQ
相关产品推荐
相关产品推荐

