问题
Background
I have a cursor used as follows:
for (int n=0; n<num_songs; n++) {
boolean isChecked = checked_positions.get(n);
if (isChecked) {
Cursor 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));
cursor.close();
//save artist and title strings to file...
}
}
This gives a StaleDataException on the second time round the loop when it tries to reuse the closed cursor. If I remove cursor.close() it runs fine but I get a "Cursor finalized without prior close" warning.
Research
The advice in this answer: https://stackoverflow.com/a/18107638/1977132 is to set the cursor to null cursor.close(); cursor = null;
presumably so a new cursor can be created, but it makes no difference, the second time round the loop it still gives a StaleDataException.
I've already tried...
I tried moving it outside the loop as follows:
Cursor cursor;
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...
}
}
cursor.close();
but this wouldn't compile with the error "cursor might not have been initialized".
Question
My question is how do I correctly use and close a cursor within a loop.
回答1:
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();
回答2:
This is the proper way to close cursor:
Cursor cursor = null;
try{
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...
}
}
} finally {
if(cursor != null){
cursor.close();
}
}
来源:https://stackoverflow.com/questions/32201617/how-to-close-a-cursor-used-in-a-for-loop