【问题标题】:A few questions about SQLite database cursors in AndroidAndroid中关于SQLite数据库游标的几个问题
【发布时间】:2022-01-04 22:49:44
【问题描述】:

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

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

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

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

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

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

  1. 我知道startManagingCursor/stopManagingCursor 已被弃用,但我不是针对Honeycomb(至少目前是这样),而且我现在不想处理新的CursorLoader。但是在上面的教程中,startManagingCursor 被到处使用,但stopManagingCursor 从来没有被调用过一次。为什么不? Android 是否以自己的方式处理这个问题?有什么情况需要拨打stopManagingCursor

【问题讨论】:

    标签: android sqlite android-cursor android-loadermanager


    【解决方案1】:

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

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

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

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

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

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

    EDIT2:关于LoaderManager的一些注释

    developer.android.com 上有 LoaderManager 教程,但这些教程非常...复杂且第一次像那里的大多数教程一样难以理解。我也不得不挖掘很多,到目前为止我发现的最好的一站式服务是http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/(加上你可以找到的所有javadocs和compat lib源)---LoaderManager的工作方式非常类似于(现在也已弃用,由DialogFragment 取代)管理对话框及其onCreateDialogonPrepareDialog 方法,您只需告诉Android“显示对话框#123”,然后Android 使用该ID 调用您的代码;加载器也一样:“load loader #123”,Android 调用 onCreateLoader()

    最初唯一明显的缺点是LoaderManager 严重依赖ContentProvider 框架,有些人似乎真的不喜欢这样。当然,这是额外的学习和代码,但是一旦您拥有一个用于您自己的数据的ContentProvider(即使只是在您的应用程序中私下使用),所有数据到视图的绑定对CursorLoader 来说都是轻而易举的事。恕我直言,推出你自己的“内容提供者”和实际实施ContentProvider 之间几乎没有区别——但这只是我极具争议的观点:)

    3) 我知道 startManagingCursor/stopManagingCursor 已被弃用 但我不是针对 Honeycomb(至少目前是这样)而且我 现在不想处理新的 CursorLoader。但在 上面的教程,startManagingCursor 到处都用到了,但是 stopManagingCursor 永远不会被调用一次。为什么不?安卓交易吗 以它自己的方式?任何我应该打电话的情况 停止管理光标?

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

    【讨论】:

    • #1 我完全误解了我对这个问题的想法,我需要重新措辞... #2 是的,我的意思是deactivate(错字)。我真的找不到任何关于如何使用LoaderManager 的好文档,甚至在 SO 问题中也找不到。 #3 我明白这一点,但如果我不应该使用stopManagingCursor,如果我打电话给startManagingCursor,为什么这个方法甚至首先存在?
    • 另外,刚刚找到#2的答案;用答案再次编辑问题。
    • 刚刚在我的全球网站上获得了第一天的曙光,现在阅读您的编辑。哦,刚刚看到:地球的同一侧,只是比你早睡了;)
    • 好了,更新了我的答案,以及LoaderManager 上的一些个人笔记。
    • 谢谢,非常感谢:) 会看一下提到的教程,也许以后我会迁移到LoaderManager
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 2011-04-09
    • 1970-01-01
    相关资源
    最近更新 更多