关于Android中SQLite数据库游标的几个问题

时间:2011-09-29 21:33:30

标签: android database sqlite cursor android-loadermanager

要在我的应用程序中实现数据库访问,我跟着Lars Vogel tutorial,但我对一些事情感到很困惑......

1)每次调用fetchTodo时,都会创建并返回一个新游标。将前一个光标留给垃圾收集器。因此,如果我不使用startManagingCursor甚至CursorLoader,那么当我完成时,我应该在光标上调用.close()吗?当然,在fetchTodo范围之外,例如:

Cursor cursor = mNotesAdapter.fetchTodo();
// do something...
cursor.close();

我已经完成了这个游标,并且会在下次获取时创建新游标,如果我这样关闭它,还是应该将它留给垃圾收集器?虽然我认为我在谈论两件完全不同的事情......重点是,我应该像上面的例子那样关闭它吗?

2) Cursor也有.deactivate()方法,文档说它使用的资源更少(比活动游标更多)。我什么时候应该使用它?例如,在我的应用程序中,我有一个ListActivity,它通过SimpleCursorAdapter填充(代码初始化只调用一次)。正在使用的游标是一个类成员变量,因为我需要在填充列表的方法之外。当从中删除某些内容时,我需要它来重新查询数据库。但是,除非删除记录,这是用户操作并且可能需要一段时间才会发生,我应该在此期间停用光标吗?因为当我再次呼叫.requery()时它将再次激活。或者SimpleCursorAdapter将停止工作,因为光标未激活?

编辑:我刚测试了这个,发现在设置游标适配器后我无法调用deactivate()。如果光标未激活,则列表将为空,因此只要显示ListActivity,它就需要保持活动状态。最后,我们应该让StartManagingCursor处理它。或新的CursorLoader

3)我知道startManagingCursor / stopManagingCursor已弃用,但我不是针对Honeycomb(至少目前为止)并且我不想现在就处理新的CursorLoader。但是在上面的教程中,startManagingCursor在任何地方都使用,但stopManagingCursor永远不会被调用一次。为什么不? Android会以自己的方式处理吗?我应该拨打stopManagingCursor的任何情况?

1 个答案:

答案 0 :(得分:9)

编辑:更新了答案以反映更新的问题1:

  

1)每次调用fetchTodo时,都会创建一个新光标   并返回。将前一个光标留给垃圾收集器。   所以,如果我不使用startManagingCursor甚至CursorLoader   那件事,我完成后应该在光标上调用.close()   它?

是的,你绝对应该告诉Android startManagingCursor(),自己使用LoaderManager / CursorLoaderclose()。不这样做会泄漏内存,因为Cursor背后有原生资源(例如数据库的文件句柄),GC无法帮助解决这个问题。

  

2)Cursor也有一个.deactive()方法,文档说明了这一点   使用较少的资源(比活动游标)。我应该什么时候使用   这个? ...

编辑给其他读者:OP找到答案并将其发布在他的问题中。以下内容仍然有效:

我从未使用deactivate()(没有deactive()),也许其他人可以解释这一点。如果你想要真正无痛的重新查询/更新,请查看LoaderManager框架 - 它不仅适用于Honeycomb:使用compat库,您可以使用LoaderManager(和Fragments)到Android 1.6。它不仅减少了您编写的代码,而且完全将这些内容卸载到Android,远远超​​过startManagingCursor()

EDIT2:LoaderManager

上的一些注释

developer.android.com上有LoaderManager个教程,但这些教程非常复杂,第一次很难理解,就像那里的大多数教程一样。我也不得不挖掘很多,到目前为止我找到的最好的一体化停靠点是http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/(加上你能找到的所有javadoc和compat lib源码)--- LoaderManager的工作方式与DialogFragmentonCreateDialog方法管理对话框非常类似(现在也已被弃用,取而代之的是onPrepareDialog),您只需告诉Android“显示对话框#123”然后Android调用你的代码与该ID;对于加载器也是如此:“加载加载程序#123”,Android调用onCreateLoader()

唯一明显的缺点是,LoaderManager在很大程度上依赖于ContentProvider框架,有些人似乎真的不喜欢它。当然,它是额外的学习和代码,但是一旦你有自己数据的ContentProvider(即使只在你的应用程序中私下使用),所有数据到视图的绑定都是轻而易举的CursorLoader 。恕我直言,滚动你自己的“内容提供者”和实际实现ContentProvider之间没有什么区别 - 但这只是我极具争议的观点:)

  

3)我知道不推荐使用startManagingCursor / stopManagingCursor   但我不是以Honeycomb为目标(至少在目前)和我   暂时不想处理新的CursorLoader。但是在   上面的教程,startManagingCursor随处可见,但是   stopManagingCursor永远不会被调用一次。为什么不? Android交易吗?   以它自己的方式?我应该打电话的任何情况   stopManagingCursor?

致电startManagingCursor()后,Cursor不再是您的问题。当Activity被破坏(用户导航,方向改变,......)时,Android将负责关闭光标。没有必要将拨打startManagingCursor()的电话与stopManagingCursor()的电话相匹配 - 您通常不希望在您摆脱后再次承担管理Cursor的责任它的。