2011-08-25 42 views
2

在Android中重新使用游标对象以在数据库上进行多个查询是否是一种很好的做法?我需要在查询之间调用deactivate()吗?我在第二个查询后停用游标,但我仍然在logcat中收到DatabaseObjectNotClosedException警告。Android重新使用游标

+1

游标不会进行查询,它保存查询的结果。我看不出有什么理由不能将它设置为空,然后重新使用它。 – Jack

+0

经过再看看文档,我相信我需要调用deactivate()然后请求一个新的游标。我不相信在请求新的游标之前将它设置为null是必要的。 – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

回答

0

以我的经验,你可以将光标设置为新的东西。我尝试过在其上调用deactivate(),但是这弄乱了我的应用程序,所以我决定不使用它。我不知道这是否是好的做法,但它对我来说工作得很好,就我的测试而言,它似乎不会泄漏或放慢速度。

0

那么,requery()已被弃用,bur由于某种原因deactivate()不是。如果没有另一个,你不能真正使用它,所以我猜你可能会认为你不应该使用deactivate()。在任何情况下,一旦完成它就关闭一个光标将消除所有那些讨厌的DatabaseObjectNotClosedException的。新的加载器框架鼓励返回新的游标,旧代码在您替换它们时会自动关闭。

+0

这是不正确的。您可以使用停用而不使用重新查询。 Requery已被弃用,因为您不需要调用它。你可以调用deactivate,然后通过调用database.rawQuery()或类似的东西来创建一个新的游标。 – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

+0

为什么叫停用呢? –

1

requery()deactivate()现在已被弃用(自API 11开始的第一个,后者自API 16开始)。我正在回答这个差不多7年的问题,因为我相信还没有给出正确的答案。

根据我的经验,重新使用Cursor对象是一种不好的做法。我的SQLiteOpenHelper类的实现有几种方法,我关闭了所有这些对象中的Cursor对象 - 并且我相信由于在每个方法结束时关闭了Cursor对象,所以它是正确的。但在某些方法中,我重新使用一个Cursor对象来保存来自多个查询的结果(首先我运行了一个查询,然后我读取并使用了Cursor的结果,然后运行了一个我认为会简单的查询覆盖已使用的Cursor中的旧结果)。启用StrictMode证明了我的错误。我开始变得DatabaseObjectNotClosedException崩溃。

我修复它不再使用Cursor对象。现在我为每个查询创建一个新的Cursor变量,然后读取并保存结果,并且我在Cursor上调用close()方法,不再使用它。如果我需要在该方法中运行另一个查询,我故意不再使用旧的Cursor,而且我总是创建一个新变量。即使启用了StrictMode,我也不会再收到任何警告或崩溃。我相信垃圾收集器的工作是正确的,所以我不认为创建Cursor类的多个实例是一个巨大的问题。另一方面,仅使用一个Cursor对象就像一个问题似乎 - 因此您的警告和我的崩溃StrictMode

我不是数据库专家,我仍然在学习Android编程的最佳实践,但我相信在这个话题上我是正确的 - 不要重复使用Cursor对象,或者您可以开始获取内存泄漏,警告甚至崩溃。