getContentResolver.query 和 managedQuery 的区别

对于Android数据库查询语句的问题

Activity 里面提供了一个 managedQuery() 方法,按照 Android SDK 里面的说明,“the activity will manage its lifecycle for you.” 听起来很好,Activity 可以替你管理 Cursor 的生命周期了,就不用记着去 close() 了,代码可以更简洁。

但是 Activity 是怎么去管理 Cursor 的生命周期的呢?SDK 文档没说。

但是有一个 bug,在一个 Activity 中,用 managedQuery() 查询数据库,将查询得到的 Cursor 用 CursorAdapter 与 ListView 绑定。然后在 Activity 里面执行批量删除数据表记录操作,因为耗时比较长,所以用了多线程处理。测试发现的 bug 是,在删除操作进行过程中,如果按下 Home 键,应用就崩溃了。崩溃原因是 Cursor 被释放了,导致工作线程的删除操作异常。

看了 Activity.java 的源码之后就明白为什么会崩溃了。managedQuery() 其实无非就是把查询得到的 Cursor 放到了 Activity 类的一个数组成员变量中,然后当 Activity stop 的时候,将这个数组里的每个 cursor 都关掉,以及在 resume 的时候,将数组里的每个 cursor 都重新查询一次。所以在按下 Home 键之后,Activity 被 stop 了,cursor 也就被关闭了,如果有个线程还在继续使用这个 cursor,就会抛异常了。

因此,在用 managedQuery() 的时候,需要清楚 cursor 什么时候会被释放,并考虑好自己的代码在 cursor 被释放后不再需要使用这个 cursor.

而query 出自android.content.ContentResolver.query,其实managedQuery的内部实现是调用了query,只是在query的基础上,加上了startManagingCursor操作,以管理获取的cursor。因此,若是只用query,且对于query返回的cursor没有进行管理的话,会造成内存的泄露问题等等。但是若是用了query后,有对返回的cursor进行了startManagingCursor操作,则这两个的效果就完全一样了。

String value = "";
String path = "";

path = "content://aaa/bbb";

Uri uri = Uri.parse(path + "/" + key);

Cursor mCursor = context.getContentResolver().query(uri, null,null, null, null);
if (mCursor != null) {
    while (mCursor.moveToNext()) {
        value = mCursor.getString(mCursor.getColumnIndex("value"));
        // Log.e("Leo", key + "=" + value);
    }
        mCursor.close();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值