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
Inject CSS to a Site with Webview in Android
Android Chrome Ignoring -Webkit-Text-Size-Adjust:None Property. Text Is Being Scaled When Zoomed Out
API Key for Gcm Is Suddenly Invalid? Unauthorized (401) Error
How to Sort Firebase Records by Two Fields (Android)
How to Animate Recyclerview Items When They Appear
Error Type 3 Error: Activity Class {} Does Not Exist
Text Size and Different Android Screen Sizes
Android: How to Validate Edittext Input
How to Prevent Screen Capture in Android
Receiving Package Install and Uninstall Events
Location of SQLite Database on the Device
Error:Execution Failed for Task ':App:Transformclasseswithdexfordebug'
What Does "Program Type Already Present" Mean
Lollipop:Draw Behind Statusbar with Its Color Set to Transparent
How to Hide Navigation Bar Permanently in Android Activity
Resources$Notfoundexception: Resource Is Not a Drawable (Color or Path)