Android重新使用游标

时间:2011-08-25 18:17:07

标签: android sqlite cursor

在android中重用游标对象在数据库上进行多次查询是不错的做法?我是否需要在查询之间调用deactivate()?我在第二次查询后停用游标,但我仍然在logcat中收到DatabaseObjectNotClosedException警告。

3 个答案:

答案 0 :(得分:1)

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

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

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

我不是数据库专家,而且我还在学习Android编程的最佳实践,但我相信在这个主题上我是正确的 - 不要重复使用{{ 1}}对象,或者你可以开始得到内存泄漏,警告甚至可能崩溃。

答案 1 :(得分:0)

根据我的经验,您可以将光标设置为新的。我已经尝试过调用deactivate(),但这搞砸了我的应用程序,所以我决定不使用它。我不知道这是不是很好,但它对我来说很好,就我的测试而言,它似乎没有泄漏或减慢任何东西。

答案 2 :(得分:0)

好吧,requery()已被弃用,由于某些原因导致deactivate()没有。你不能真正使用另一个,所以我猜你可以假设你不应该使用deactivate()。在任何情况下,一旦你完成它就关闭光标将摆脱所有那些讨厌的DatabaseObjectNotClosedException。新的加载器框架鼓励返回新游标,旧游标会在您更换时自动关闭。