boolean android.database.Cursor.moveToNext()文档说:
http://developer.android.com/reference/android/database/Cursor.html#moveToNext%28%29
将光标移动到下一行。
如果光标已经超过结果集中的最后一个条目,则此方法将返回false。
但是,我的书说要从光标中提取数据:
Cursor myCursor = myDatabase.query(...); if (myCursor.moveToFirst()) { do { int value = myCursor.getInt(VALUE_COL); // use value } while (myCursor.moveToNext()); }
谁是对的?这两者都不可能是真的。如果你看不到矛盾,想象一下myCursor从查询中返回了1行。对getInt()的第一次调用将起作用,但随后moveToNext()将返回true,因为它不是“已经”超过结果集中的最后一个条目。所以现在光标将超过最后一个条目,第二次调用getInt()会做一些未定义的事情。
我怀疑文档是错误的,应该改为:
如果光标“已经在”结果集中的最后一个条目,则此方法将返回false。
在moveToNext()方法返回false之前,光标必须已经是PAST(不是AT)的最后一个条目吗?
没有Snark请
答案 0 :(得分:21)
一个更简单的习语是:
Cursor cursor = db.query(...);
while (cursor.moveToNext()) {
// use cursor
}
这是因为初始光标位置为-1,请参阅Cursor.getPosition()文档。
您还可以使用此Google Code Search query在Android源代码中找到游标的用法。 SQLite数据库和内容提供者中的游标语义相同。
参考文献:this question。
答案 1 :(得分:6)
来自API的逐字:
返回: 此举是否成功。
所以,这意味着:
第一行中的光标 - > moveToNext() - >光标在第二行 - >没有第二行 - >返回错误
public final boolean moveToNext() {
return moveToPosition(mPos + 1);
}
public final boolean moveToPosition(int position) {
// Make sure position isn't past the end of the cursor
final int count = getCount();
if (position >= count) {
mPos = count;
return false;
}
答案 2 :(得分:2)
我认为我倾向于远离基于隐藏假设的解决方案,例如:我希望sqlite永远不会改变api,并且游标总是从第一项开始。
此外,我几乎总能用for语句替换while语句。所以我的解决方案显示了我期望光标开始的内容,并避免使用while语句:
for( boolean haveRow = c.moveToFirst(); haveRow; haveRow = c.moveToNext() ) {
...
}
为什么显示游标需要从第一行开始,就在你可能正在调试自己的代码的6个月之后,并且会想知道你为什么不明确这样做以便你可以轻松地调试它。 / p>
答案 3 :(得分:2)
它似乎取决于AbstractCursor的Android实现,它在Jellybean中仍然存在。
我实施了以下单元测试,以使用MatrixCursor向我自己演示问题:
@Test
public void testCursor() {
MatrixCursor cursor = new MatrixCursor(new String[] { "id" });
for (String s : new String[] { "1", "2", "3" }) {
cursor.addRow(new String[] { s });
}
cursor.moveToPosition(0);
assertThat(cursor.moveToPrevious(), is(true));
cursor.moveToPosition(cursor.getCount()-1);
assertThat(cursor.moveToNext(), is(true));
assertThat(cursor.moveToPosition(c.getCount()), is(true));
assertThat(cursor.moveToPosition(-1), is(true));
}
所有断言都失败了,与moveToNext,moveToPrevious和moveToPosition的文档相反。
在API 16中读取AbstractCursor.moveToPosition(int position)的代码,它似乎是有意的行为,即在这些情况下方法显式返回false,与文档相反。
作为旁注,由于Android代码在野外的现有设备上无法更改,我采用编写代码的方法来匹配现有Android实现的行为,而不是文档。即。在实现我自己的Cursors / CursorWrappers时,我重写方法并编写自己的javadoc来描述与现有文档的偏离。这样,我的Cursors / CursorWrappers仍然可以与现有的Android游标互换,而不会破坏运行时行为。
答案 4 :(得分:0)
返回布尔值的Cursor.moveToNext()仅在它不会将光标移过数据集中的最后一个条目时才有用。因此,我已经提交了关于文档问题跟踪器的错误报告。
https://issuetracker.google.com/issues/69259484
它推荐以下句子:
“如果当前(执行时)条目是集合中的最后一个条目,并且没有下一个条目,则此方法将返回false。”