android 高级之旅 (十六) Android 数据库操作中的cursor错误!

做android 开发的经常会遇android.database.CursorWindowAllocationException这样子的错误;一般出现这样的错误,大部分原因是因为没有关闭cursor,或者是因为Cursor使用不当,之前我的遇到这样的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ForecastData situation = null ;
     ................
     Cursor cursor = mContext.getContentResolver().query(WEATHER_URI, null ,
     null , null , null );
 
     try {
         if (cursor != null && cursor.moveToFirst()) {
         ...........
         cursor.close();
         }
    } catch (Exception e) {
         e.printStackTrace();
    } finally {
         if (cursor != null ) {
         cursor.close();
    }
}
return situation;
 
}
初看一下没有什么问题,但如果Cursor cursor = mContext.getContentResolver().query这里返回的错误还是会有可能造成程序的未关闭Cursor,因此我们改成标准写法:

?
1
2
3
4
5
6
7
8
9
Cursor cursor = null ;
try {
     cursor = getContentResolver().query(URI, .....); // 1
         //dosomething
} finally {
     if (cursor != null ) {
         cursor.close(); // 2
     }
}
这样改了之后,运行了很多个版本都一直没有问题。直到有一天一个同事发现可能查询 数据库比较耗时。因此把方法放到线程里面去执行,而已每次查询的时候都会创建一个线程。没有想到上面代码又出错误了,如果您稍不留意不会怀疑这块代码的问题,因为try-finally写法不存在逻辑上的问题。由于这里未考虑到多线程场景,try-finally并不能保证query打开游标在dosomething时,被其他线程再次调用query打开游标。所以当遇到存在多线程的调用时必须对游标打开到关闭时间段添加锁,即这里是对try-finally块加锁。

下面简单解释一下:

假设:线程A执行到1处创建了一个Cursor,然后dosomething比较耗时……..

线程B又来查询数据库,因此到1处又创建一个Cursor,此时如果AB执行完,就会关闭锁,看起来没有问题,但由于是同一个对象,所以AB关闭的cursor都是B创建的,因此
A创建的Cursor就没有关闭!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值