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

发布于 2024-12-07 10:34:49 字数 1462 浏览 1 评论 0原文

为了在我的应用程序中实现数据库访问,我遵循了 Lars Vogel 教程,但是我'我对一些事情感到非常困惑...

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

    光标cursor = mNotesAdapter.fetchTodo(); // 做某事... 光标.close();

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

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

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

  1. 我知道 startManagingCursor/stopManagingCursor 已被弃用,但我不以 Honeycomb 为目标(至少暂时如此),并且我不想处理新的CursorLoader。但在上面的教程中,startManagingCursor 随处使用,但 stopManagingCursor 从未被调用过一次。为什么不呢? Android 是否以自己的方式处理这个问题?在什么情况下我应该调用 stopManagingCursor

To implement database access in my application I followed Lars Vogel tutorial, but I'm very confused about a couple of things...

  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 ? Outside of fetchTodo scope of course, example:

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

I'm done with this cursor and new one will be created on the next fetch, should I close it like this then or should I leave it for the garbage collector? Although I think I'm talking about 2 things entirely different... Point being, should I close it like in the example above or not?

  1. Cursor also has a .deactivate() method and the documentation says it uses less resources (than active cursors). When exactly should I use this? For instance, in my app, I have a ListActivity which is populated through a SimpleCursorAdapter (the code initialization for this is only called once). The cursor being used is a class member variable, because I need it outside the method that populates the list. I need it to requery the database when something is deleted from it. But until a record is deleted, which is a user action and may take a while to happen, should I deactivate the cursor in the meantime? Cause it will be active again when I call .requery() again. Or the SimpleCursorAdapter is going to stop working because the cursor is not active?

EDIT: I just tested this one and found out that I can't call deactivate() after setting up the cursor adapter. The list will be empty if the cursor is not active, so it needs to remain active for as long as the ListActivity is displayed. In the end, we should just let StartManagingCursor handle it then. Or the new CursorLoader.

  1. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拒绝两难 2024-12-14 10:34:49

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

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

是的,您绝对应该告诉 Android startManagingCursor()、使用 LoaderManager/CursorLoaderclose()你自己。不这样做会泄漏内存,GC 对此无济于事,因为光标后面有本机资源(例如数据库的文件句柄)。

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

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

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

EDIT2:关于 LoaderManager 的一些

注释第一次像那里的大多数教程一样。我还必须进行大量挖掘,迄今为止我发现的最好的一站式服务是 http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/ (加上所有 javadocs 和 compat lib 源,您可以find) --- LoaderManager 的工作方式与(现在也已弃用,由 DialogFragment 取代)托管对话框及其 onCreateDialog 非常相似, onPrepareDialog 方法,您只需告诉 Android“显示对话框 #123”,然后 Android 使用该 ID 调用您的代码;对于加载器也是如此:“load loader #123”,Android 调用 onCreateLoader()

唯一明显的缺点是最初,LoaderManager 严重依赖 ContentProvider 框架,有些人似乎真的不喜欢这一点。当然,这是额外的学习和代码,但是一旦您为自己的数据拥有了 ContentProvider (即使仅在您的应用程序中私下使用),所有数据到视图的绑定都会变得轻而易举>光标加载器。恕我直言,滚动您自己的“内容提供程序”和实际实现 ContentProvider 之间几乎没有什么区别 - 但这只是我备受争议的观点:)

3) 我知道 startManagingCursor/stopManagingCursor 已弃用
但我的目标不是 Honeycomb(至少暂时如此)并且我
现在不想处理新的 CursorLoader。但在
上面的教程中,startManagingCursor 到处都用到了,但是
stopManagingCursor 永远不会被调用一次。为什么不呢?安卓有优惠吗
以它自己的方式?任何情况我应该打电话
停止管理光标?

一旦您调用 startManagingCursor()Cursor 就不再是您的问题。当您的 Activity 被破坏(用户离开、方向改变等)时,Android 将负责关闭光标。无需将对 startManagingCursor() 的调用与对 stopManagingCursor() 的调用相匹配 - 您通常不想承担管理 的负担一旦你摆脱它,再次>光标

Edit: Updated answer to reflect updated question 1:

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 ?

Yes, you should definitely either tell Android to startManagingCursor(), use LoaderManager/CursorLoader or close() it yourself. Not doing so will leak memory, the GC won't help with that as there's native resources behind the Cursor (e.g. file handles to the database).

2) Cursor also has a .deactive() method and the documentation says it
uses less resources (than active cursors). When exactly should I use
this? ...

EDIT to other readers: The OP found an answer and posted it in his question. The following still holds:

I've never used deactivate() (there's no deactive()), maybe someone else can explain this. If you want really painless requery/updates, do check out the LoaderManager framework -- it's not only for Honeycomb: using the compat library you can use LoaderManager (and Fragments) down to Android 1.6. Not only is it less code for you to write, but it completely offloads these things to Android, much more so than startManagingCursor().

EDIT2: Some notes on LoaderManager

There are LoaderManager tutorials on developer.android.com but these are quite... complex and hard to understand the first time like most of the tutorials there. I also had to dig a lot, the best all-in-one stop I found so far is http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/ (plus all the javadocs and compat lib source you can find) --- the way LoaderManager works is very similar to the (now also deprecated, replaced by DialogFragment) managed dialogs with their onCreateDialog, onPrepareDialog methods where you just tell Android to "show dialog #123" and then Android calls your code with that ID; same for loaders: "load loader #123", Android calls on onCreateLoader().

The only obvious drawback is initially, that LoaderManager relies heavily on the ContentProvider framework and some people seem to really dislike that. Sure, it's additional learning and code, but once you have a ContentProvider for your own data (even if only used privately in your app), all the data-to-view bindng is a breeze with CursorLoader. IMHO, there's little difference between rolling your own "content provider" and actually implementing the ContentProvider -- but this is just my highly controversial opinion :)

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?

Once you call startManagingCursor() the Cursor is no longer your problem. Android will take care of closing the Cursor when your Activity gets destroyed (user navigates away, orientation change, ...). There's no need to match a call to startManagingCursor() with a call to stopManagingCursor() -- you usually don't want to take on the burden of managing a Cursor again once you've gotten rid of it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文