刚开始,我还以为我是我 insert 代码有问题,然后仔细查看了下,没发现问题。打印 dao 以及 helper 发现其值也不为 null,那么为什么会出现空指针异常呢?
然后,我将 insert() 中的逻辑抽取出来,放入单元测试类中。如下:
public void test(){
DBHelper helper = new DBHelper(getContext());
SQLiteDatabase db = helper.getWritableDatabase();
String table = "tb_url_down";
ContentValues values = new ContentValues();
values.put("url", "http://www.baidu.com");
values.put("dirName", "baidu");
long rs = db.insert(table, null, values);
Log.i(TAG, rs + "");
}执行,结果显示:
这样的结果,让我顿时要抓狂了,这是搞莫子鬼罗?明明一样的逻辑,不同的运行结果。再次细细的对比,还是没发现问题啊!没办法,既然报错,肯定是有 bug 的,通过不断的测试,我发现,程序运行在 insert() 方法的第一行就开始报“空指针异常”了。这是什么情况?再次debug,调试代码如下:
public void test(){
DBHelper helper = new DBHelper(getContext());
SQLiteDatabase db = helper.getWritableDatabase(); // 我在此处加了断点
int i = 1 /0;// 为了抛出异常以便调试,不然直接就执行完毕了
String table = "tb_url_down";
ContentValues values = new ContentValues();
values.put("url", "http://www.baidu.com");
values.put("dirName", "baidu");
long rs = db.insert(table, null, values);
Log.i(TAG, rs + "");
}还是一样的代码,仅仅是加了一行错误语句而已。debug 显示结果如下:
然后,在 debug 一下 testInsert() 方法,显示如下:
对比二者刚刚画红线的 helper,发现第二次调试的 mContext 居然是 null!这是为什么?不是应该在单元测试类 BaseDaoImpl dao = new BaseDaoImpl(getContext()); 时已经传递进去了吗?然后就着程序猿认真的态度,改了下代码试了一下,代码如下:
public void testInsert(){
// 注意:一定注意,这个不能放在外面初始化,否则一直出现空指针错误
dao = new BaseDaoImpl(getContext());
String table = "tb_url_down";
ContentValues values = new ContentValues();
values.put("url", "http://www.baidu.com");
values.put("dirName", "baidu");
boolean rs = this.dao.insert(table, values);
if(rs){
Log.i(TAG, "插入成功!");
} else {
Log.i(TAG, "插入失败!");
}
}仅仅是增加了一行代码,然后执行结果截然不同了,运行如下:
成功了,成功了!太心酸了。被这个错误折磨好久,终于解决了,太不容易了
。