用 managedQuery() 时须要注意的一个陷阱
2014-10-15 12:03
197 查看
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.
可是 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.
相关文章推荐
- 用 managedQuery() 时须要注意的一个陷阱
- 用 managedQuery() 时需要注意的一个陷阱
- C++在使用Qt中SLOT宏须要注意的一个小细节
- 可变参数模拟printf()函数实现一个my_print()函数以及调用可变参数需注意的陷阱
- vc 设置随机数种子需要注意的一个陷阱
- 关于异或的用法1交换整数(注意陷阱)2求整数序列中差的一个值
- PHP DOM操作xml文档,删除一个,遍历删除所有(注意有陷阱)
- C++ 程序员转 C#要注意的一个foreach陷阱
- boiz 的C++ 备忘录(三)-- 注意strcpy函数的一个陷阱
- 使用RegistryKey的一个注意点
- ado recordset的一个陷阱
- 编程中注意的一个问题
- 博客园的一个逻辑Bug,dudu要注意
- 注意招聘陷阱(zt)
- [原创]使用DropDownlist时应该注意的一个小问题
- 【注意】一个巨牛的招聘题(ZZ)
- 运行Nokia模拟器的一个注意事项
- SWT的GridData中一个需要注意的地方
- 编程中注意的一个问题
- 一个24小时内点击最高的新闻sql语句 + require()注意事项