Android SQLite调用insert方法报空对象引用错误如何解决?
问题根因
该空指针错误的核心是调用insertYec_product方法的dataBaza实例未完成初始化,处于null状态。
报错信息:
java.lang.NullPointerException: Attempt to invoke virtual method 'long com.example.carpetcatalog.DataBaza.insertYec_product(com.example.carpetcatalog.Models.YecProductForDB)' on a null object reference at com.example.carpetcatalog.MainActivity$4.onResponse(MainActivity.java:374)
排查步骤
- 检查MainActivity中
dataBaza的初始化逻辑。SQLiteOpenHelper的实例化必须在调用数据库操作前完成,确认是否在Activity的onCreate方法里执行了dataBaza = new DataBaza(MainActivity.this)类的初始化代码,是否存在代码漏写,或者初始化代码执行时机晚于networkCallbackForProduct的调用时机。 - 检查网络请求的触发时机。如果在Activity还没完成初始化的时候就发起了网络请求,或者异步请求回调回来的时候Activity已经被销毁、
dataBaza已经被置空,也会触发该问题。 - 检查代码混淆或者实例销毁逻辑。如果项目开启了混淆,确认是否给DataBaza类加了混淆豁免规则;另外确认是否在
onStop、onDestroy等生命周期回调里提前把dataBaza赋值为null,但网络请求的异步回调还未结束。
解决方案
- 补全
dataBaza的初始化逻辑,确保在调用networkCallbackForProduct之前完成初始化,示例代码如下:
// 在MainActivity的onCreate方法中添加 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 优先初始化数据库实例 dataBaza = new DataBaza(this); // 再执行网络请求 networkCallbackForProduct(); }
- 增加空判断防护,在调用数据库操作前先判断
dataBaza是否为null,同时对返回的响应体加非空判断,避免二次空指针:
// 先判断响应体是否非空 if (response.body() == null) { Toast.makeText(MainActivity.this, "返回数据为空", Toast.LENGTH_SHORT).show(); return; } List<Yec_product> productList = response.body(); for (Yec_product product : productList) { YecProductForDB yecProductForDB = new YecProductForDB(product.getId(), product.getCode(), product.getName(), product.getImage_url(), product.getPrice(), product.getQuality_id(), product.getRoom_id(), product.getChanged()); // 增加数据库实例非空判断 if (dataBaza != null) { long natija=dataBaza.insertYec_product(yecProductForDB); if (natija==-1){ Toast.makeText(MainActivity.this, "error insert baza product", Toast.LENGTH_SHORT).show(); finish(); } } else { Toast.makeText(MainActivity.this, "数据库未初始化", Toast.LENGTH_SHORT).show(); } }
- 如果是页面销毁导致的空指针,在页面销毁的时候取消网络请求,避免无效回调执行:
@Override protected void onDestroy() { super.onDestroy(); // 取消未完成的网络请求 if (productresponse != null && !productresponse.isCanceled()) { productresponse.cancel(); } // 关闭数据库连接 if (dataBaza != null) { dataBaza.close(); dataBaza = null; } }
内容的提问来源于stack exchange,提问作者Jahongir Rajabaliyev
相关产品推荐
相关产品推荐

