用 managedQuery() 时需要注意的一个陷阱
2011-11-16 14:13
260 查看
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() 时须要注意的一个陷阱
- vc 设置随机数种子需要注意的一个陷阱
- 开发一个蓝牙耳机所需要注意的事项
- 写一个类需要注意的一些要点
- 控制器中方法需要注意的一个问题
- 产品经理需要注意的4个逻辑陷阱
- Java NIO开发需要注意的陷阱(转)
- php中使用$_REQUEST需要注意的一个问题
- 关于协方差矩阵需要注意的一个事项
- 建议64:为循环增加Tester-Doer模式而不是将try-catch置于循环内 如果需要在循环中引发异常,你需要特别注意,应为抛出异常是一个相当影响性能的过程。应该尽量在循环当中对异常发生的一
- 如果一个页面中用了两个以上displaytag,需要注意的分页问题
- “js 判断变量是否为空”需要注意的陷阱
- socket运用中需要注意的一个问题
- 一个简单的动画需要注意的坑
- goroutine 需要注意的一个小细节
- spring 容器后处理器 BeanFactoryPostProcessor 使用需要注意的一个问题
- PHP的foreach中使用引用时需要注意的一个问题和解决方法
- SqlServer中使用Select语句给变量赋值的时候需要注意的一个问题
- sqoop之从oracle导入hbase的问题与sqoop hbase 需要注意的一个问题