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) Every time a call is made to fetchTodo a new cursor will be created
and returned. Leaving the prevIoUs cursor for the garbage collector.
So,if I don’t use startManagingCursor or even the CursorLoader for
that matter,should I call a .close() on the cursor when I’m done with
it ?
是的,你绝对应该告诉Android startManagingCursor(),使用LoaderManager / CursorLoader或者自己关闭().不这样做会泄漏内存,因为Cursor背后有本机资源(例如数据库的文件句柄),GC无法帮助解决这个问题.
2) Cursor also has a .deactive() method and the documentation says it
uses less resources (than active cursors). When exactly should I use
this? …
编辑给其他读者: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/(加上你能找到的所有javadocs和compat lib源码)— LoaderManager的工作方式非常类似于(现在也是如此)已弃用,由DialogFragment取代)托管对话框及其onCreateDialog,onPrepareDialog方法,您只需告诉Android“显示对话框#123”,然后Android使用该ID调用您的代码;同样适用于加载器:“load loader#123”,Android调用onCreateLoader().
唯一明显的缺点是,最初,LoaderManager严重依赖于ContentProvider框架,有些人似乎真的不喜欢它.当然,它是额外的学习和代码,但是一旦你拥有了一个ContentProvider用于你自己的数据(即使只在你的应用程序中私下使用),所有数据到视图的绑定都是轻而易举的CursorLoader.恕我直言,滚动你自己的“内容提供者”和实际实现ContentProvider之间没什么区别 – 但这只是我极具争议的意见:)
3) I know that startManagingCursor/stopManagingCursor are deprecated
but I’m not targeting Honeycomb (at least for the time being) and I
don’t want to deal with the new CursorLoader for now. But in the
tutorial above,startManagingCursor is used everywhere,but
stopManagingCursor is never called once. Why not? Does Android deals
with that in it’s own way? Any situation I should call
stopManagingCursor?
一旦调用startManagingCursor(),Cursor就不再是你的问题了.当您的Activity被销毁(用户导航,方向更改,……)时,Android将负责关闭Cursor.没有必要将对startManagingCursor()的调用与对stopManagingCursor()的调用相匹配 – 一旦你摆脱了它,你通常不想承担再次管理Cursor的负担.