What's the Best Way to Iterate an Android Cursor

What's the best way to iterate an Android Cursor?

The simplest way is this:

while (cursor.moveToNext()) {
...
}

The cursor starts before the first result row, so on the first iteration this moves to the first result if it exists. If the cursor is empty, or the last row has already been processed, then the loop exits neatly.

Of course, don't forget to close the cursor once you're done with it, preferably in a finally clause.

Cursor cursor = db.rawQuery(...);
try {
while (cursor.moveToNext()) {
...
}
} finally {
cursor.close();
}

If you target API 19+, you can use try-with-resources.

try (Cursor cursor = db.rawQuery(...)) {
while (cursor.moveToNext()) {
...
}
}

How do you iterate over a cursor in reverse order

There are at least two options.

First, to specifically answer your question about iterating backwards over the cursor, you could do the following:

for (cursor.moveToLast(); !cursor.isBeforeFirst(); cursor.moveToPrevious()) {
// get stuff from the cursor
}

Second, you could populate the cursor in reverse order from sql and then iterate over the cursor in your normal way:

SQLiteDatabase db = myHelper.getWritableDatabase();
String[] columns = { MyDatabaseHelper.TEST_DATE, MyDatabaseHelper.SCORE };
String orderBy = MyDatabaseHelper.TEST_DATE + " DESC"; // This line reverses the order
Cursor cursor = db.query(MyDatabaseHelper.TESTS_TABLE_NAME, columns,
null, null, null, null, orderBy, null);

while (cursor.moveToNext()) {
// get stuff from the cursor
}

cursor.close();
db.close();

Kotlin on Android: map a cursor to a list

This is what I went with in the end, using kotlin.sequences.generateSequence...

val list = generateSequence { if (c.moveToNext()) c else null }
.map { getStringFromCursor(it) }
.toList()

My first attempt was a little shorter:

val list = (1 .. c.count).map {
c.moveToNext()
getStringFromCursor(c)
}

Both versions rely on the cursor initially being positioned before the first record (as a new cursor is). The second would throw if that wasn't the case, while the first would return a shorter list.

Android Cursor not looping through rows

Change the loop like this:

...
if (c.moveToFirst()) {
int rows = c.getCount();
do {
int j = c.getInt(0);
// Do something with j
} while(c.moveToNext());
}
...

Iterate Through Cursor, moveToNext() Does Not Appear To Work

Your problem is that getDatabaseItemsData calls moveToFirst again.

You should change getDatabaseItemsData so that it assumes that the cursor is already positioned on a valid record, i.e., just remove the moveToFirst call.

How to close a cursor used in a for loop

Try this

Cursor cursor = null;
for (int n=0; n<num_songs; n++) {
boolean isChecked = checked_positions.get(n);
if (isChecked) {
cursor = (Cursor) getListView().getItemAtPosition(n);
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
//save artist and title strings to file...
}
}
if(cursor != null)
cursor.close();


Related Topics



Leave a reply



Submit