Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 光标如何引用已删除的行?_Android_Sqlite - Fatal编程技术网

Android 光标如何引用已删除的行?

Android 光标如何引用已删除的行?,android,sqlite,Android,Sqlite,当我从Android中的sqlite DB查询返回一个游标时,它似乎包含固定数量的行,无论DB发生什么变化,这些行都不会改变。例如,如果在光标打开时删除了某些行,我仍然可以引用已删除的行。这很好,但它是如何工作的 一种猜测可能是sqlite知道我有一个指向该行的光标,因此保留了旧数据的副本。但是,如果我有一百万行,删除它们,并用一百万行不同的行替换它们,那该怎么办?似乎有很多数据需要缓存 更新: 我现在认为,我们在Android中看到的这种缓存并不是真正的防弹,也不是SQLite的一部分。我创建

当我从Android中的sqlite DB查询返回一个游标时,它似乎包含固定数量的行,无论DB发生什么变化,这些行都不会改变。例如,如果在光标打开时删除了某些行,我仍然可以引用已删除的行。这很好,但它是如何工作的

一种猜测可能是sqlite知道我有一个指向该行的光标,因此保留了旧数据的副本。但是,如果我有一百万行,删除它们,并用一百万行不同的行替换它们,那该怎么办?似乎有很多数据需要缓存

更新:

我现在认为,我们在Android中看到的这种缓存并不是真正的防弹,也不是SQLite的一部分。我创建了一个测试,它构建了一个包含1000000行的数据库,然后我查询数据库,打印出一些结果并让光标保持打开状态,然后我删除了一半行,最后我尝试访问我保持打开状态的光标,结果是崩溃:

04-05 18:17:16.141 E/AndroidRuntime(19655): java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.CursorWindow.nativeGetLong(Native Method)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.CursorWindow.getLong(CursorWindow.java:507)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at com.jacob.DirectDbActivity$4.run(DirectDbActivity.java:88)

这似乎是Android中的一个缺陷,因为大多数数据库都很小,缓存窗口可以保存所有结果,但在大型数据库中,这会影响到您。

上次我检查时,光标是基于创建它的SQL的数据库快照。很像一个数据集。如果更改数据库,光标可能不知道其快照是旧的。您可以在游标上执行重新查询,以基于创建游标的原始SQL获取新数据。

我发现这个页面()上写着“SQLite使用动态内存分配…保存查询结果”。这似乎表明结果缓存在内存中,虽然如果结果集非常大,显然会有一些限制,但我猜如果缓存太大,必须在某个时候创建一个临时文件。我认为你是对的,但我想知道是否有更完整的文档在这方面。从SQLiteDatabase文档:游标对象,它位于第一个条目之前。请注意,游标未同步,有关详细信息,请参阅文档。是否有指向此文档的链接?我想了解更多信息,是否有临时文件写入文件系统?这似乎是对包含许多行的查询的一个很大的惩罚。