关于Android中的SQLite数据库游标的几个问题 [英] A few questions about SQLite database cursors in Android

查看:154
本文介绍了关于Android中的SQLite数据库游标的几个问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要在我的应用程序中实施数据库访问,我遵循 Lars Vogel教程,但我对一些事情很困惑...



1)每次调用 fetchTodo 将创建并返回一个新的游标。离开垃圾回收器的上一个游标。所以,如果我不使用 startManagingCursor 或甚至 CursorLoader ,我应该调用 .close()在游标完成后? fetchTodo 范围外的示例:

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

我已经完成了这个游标,新的一个会在下一次抓取时创建,它喜欢这个或者我应该留给垃圾收集器?虽然我想我说的两件事情完全不同...点是,我应该像上面的例子中一样关闭它吗?



2) c> 也有一个 .deactivate()方法,文档说它使用更少的资源光标)。什么时候应该使用这个?例如,在我的应用程序中,我有一个 ListActivity ,它通过 SimpleCursorAdapter 填充只调用一次)。所使用的游标是类成员变量,因为我需要它在填充列表的方法之外。我需要它来重新查询数据库时,从它删除的东西。但是,直到一个记录被删除,这是一个用户操作,可能需要一段时间才发生,我应该停用游标的同时吗?因为当我再次调用 .requery()时,它将再次处于活动状态。或者 SimpleCursorAdapter 将停止工作,因为游标不活动?



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



3)我知道 startManagingCursor / stopManagingCursor 已废弃,但我不是针对Honeycomb(至少暂时),我不想处理新的 CursorLoader 现在。但是在上面的教程中, startManagingCursor 无处不在,但 stopManagingCursor 从不调用一次。为什么不? Android是否以自己的方式处理?任何情况我应该调用 stopManagingCursor

解决方案

反映更新的问题1:


1)每次调用fetchTodo时,将创建一个新的游标并返回。离开垃圾回收器的上一个游标。
所以,如果我不使用startManagingCursor或者甚至CursorLoader为
重要,我应该调用一个.close()在游标,当我完成了
it?


是的,你应该告诉Android startManagingCursor(),使用 LoaderManager / CursorLoader close()不这样做会泄漏内存,GC不会帮助那些,因为有 Cursor (例如数据库的文件句柄)后面的原生资源。

$ b 2)Cursor也有一个.deactive()方法,文档说它
使用比活动游标少的资源。当我应该使用
这个吗? ...


编辑:OP找到一个答案并张贴在他的问题中。以下内容仍然适用:



我从未使用过 deactivate() (没有 deactive()),也许别人可以解释这个。如果你想要非常痛苦的重新查询/更新,请检查 LoaderManager 框架 - 它不仅仅是Honeycomb:使用compat库可以使用 LoaderManager (和 Fragments )下载到Android 1.6。不仅是你写的代码少,而且它完全卸载了这些东西给Android,比 startManagingCursor()



EDIT2: LoaderManager上的一些注释



code> LoaderManager tutorials on developer.android.com但是这些都是相当...复杂和难以理解的第一次像大多数教程那里。我还要挖了很多,我发现到目前为止最好的一站式停止是 http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/ (加上所有的javadocs和compat lib源码,你可以找到)---方式 LoaderManager 工作非常类似于(现在也已弃用,由 DialogFragment 替代)托管对话框与他们的 onCreateDialog onPrepareDialog 方法,你只是告诉Android显示对话框#123,然后Android调用您的代码与该ID;相同的加载器:加载加载器#123,Android调用 onCreateLoader()



最初, LoaderManager 严重依赖 ContentProvider 框架,有些人似乎真的不喜欢。当然,它是额外的学习和代码,但一旦你有一个 ContentProvider 为你自己的数据(即使只在你的应用程序中使用私有),所有的数据到视图绑定是一个微风与 CursorLoader 。 IMHO,滚动自己的内容提供者和实际实现 ContentProvider 之间没有什么区别 - 但这只是我非常有争议的意见:)


3)我知道startManagingCursor / stopManagingCursor已弃用
,但我不是针对Honeycomb(至少暂时)和I
不想现在处理新的CursorLoader。但是在上面的
教程中,startManagingCursor随处可用,但
stopManagingCursor从不调用一次。为什么不? Android是否以自己的方式处理
?任何情况我应该调用
stopManagingCursor?


一旦你调用 startManagingCursor $ c> Cursor 不再是你的问题。当你的 Activity 被销毁(用户导航离开,方向改变,...)时,Android将关闭Cursor。没有必要通过调用 stopManagingCursor()来匹配对 startManagingCursor()的调用 - t想要承担管理光标的负担,一旦你已经摆脱它。


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?

2) 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.

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?

解决方案

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.

这篇关于关于Android中的SQLite数据库游标的几个问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆