"Attempted to access a cursor after it has been closed"

"Attempted to access a cursor after it has been closed"

我无法理解这个问题。我试图从其他 Whosebug 问题中获得解决方案,但未能获得解决方案。我之前没有收到此错误。但是,现在我不知道下面所述的代码有什么问题。请帮我解决一下这个。我被这个问题困住了。

public void getAlbumsLists() {
    final Uri uri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
    final String _id = MediaStore.Audio.Albums._ID;
    final String album = MediaStore.Audio.Media.ALBUM;
    final String album_name = MediaStore.Audio.AlbumColumns.ALBUM;
    final String artist = MediaStore.Audio.AlbumColumns.ARTIST;
    final String tracks = MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS;
    //  final String data=MediaStore.Audio.Albums.ALBUM_ID; // NO
    // final String id1=MediaStore.Audio.Albums.ALBUM_ID;
    final String tit = MediaStore.Audio.Albums.ALBUM; //NO
    final String nam = MediaStore.Audio.Albums.ALBUM_KEY; // NO
    final String typ = MediaStore.Audio.Media.MIME_TYPE; // NO
    final String art = MediaStore.Audio.Albums.ALBUM_ART; //<<<< CAN GET
    final String artstkey = MediaStore.Audio.Artists.ARTIST_KEY; //<<<< CAN GET
    final String frstyr = MediaStore.Audio.AlbumColumns.FIRST_YEAR; //<<<< CAN GET
    final String lstyr = MediaStore.Audio.AlbumColumns.LAST_YEAR; //<<<< CAN GET
    final String artstid = "artist_id"; //<<<< CAN GET

    final String[] columns = {"*"};

     Cursor cursor = getActivity().getContentResolver().query(uri, columns, null, null, null);
    // Lists the columns in the cursor
    for (String s : cursor.getColumnNames()) {
        Log.d("COLUMNS", "Column = " + s);
    }

    while (cursor.moveToNext()) {
        String id = (cursor.getString(cursor.getColumnIndex(_id)));
        String name = cursor.getString(cursor.getColumnIndex(album_name));
        String artist2 = cursor.getString(cursor.getColumnIndex(artist));
        String nr = cursor.getString(cursor.getColumnIndex(tracks));
        String x = (cursor.getString(cursor.getColumnIndex(album)));
        //String data1=cursor.getString(cursor.getColumnIndexOrThrow(data)); //<<<< NOT A COLUMN
        // String id2=cursor.getString(cursor.getColumnIndex(data));
        //String title=cursor.getString(cursor.getColumnIndex(tit)); //<<<< NOT A COLUMN
        //String name1=cursor.getString(cursor.getColumnIndex(nam)); //<<<< NOT A COLUMN
        //String type=cursor.getString(cursor.getColumnIndex(typ)); //<<<< NOT A COLUMN
        // AVAIALABLE COLUMNS
        String artwork = cursor.getString(cursor.getColumnIndex(art)); //<<<< ADDED
        String artistkey = cursor.getString(cursor.getColumnIndex(artstkey)); //<<<< ADDED
        String artistid = cursor.getString(cursor.getColumnIndex(artstid)); //<<<< ADDED
        String minyear = cursor.getString(cursor.getColumnIndex(frstyr));
        String maxyear = cursor.getString(cursor.getColumnIndex(lstyr));

        s = new albumInfo(id, name, artist2, nr, artwork, x); // EXCLUDED
        albumList.add(s);

        cursor.close();
        recyclerView1.setAdapter(albumAdapter); // EXCLUDED
    }
}

cursor.close(); 移到 while 循环之外。

已编辑..

while 循环迭代后第一次关闭游标,因此需要将其放在 while 之外。

我可以提出三个改进方案。

  1. 您需要先将光标移动到 first 才能访问它以从光标中获取数据。
  2. 没有返回或游标为空时需要关闭游标。
  3. 将光标移到 while 循环之外。

所以我想建议你像下面这样重写代码。

// After you have fetched the data from cursor
if(cursor == null) return;
if(cursor.size() == 0) {
    cursor.close();
    return;
}

for (String s : cursor.getColumnNames()) {
    Log.d("COLUMNS", "Column = " + s);
}

// Move the cursor to the first position. 
cursor.moveToFirst();
do {
    String id = (cursor.getString(cursor.getColumnIndex(_id)));
    String name = cursor.getString(cursor.getColumnIndex(album_name));
    String artist2 = cursor.getString(cursor.getColumnIndex(artist));
    String nr = cursor.getString(cursor.getColumnIndex(tracks));
    String x = (cursor.getString(cursor.getColumnIndex(album)));
    // ... Other code 
} while (cursor.moveToNext());

recyclerView1.setAdapter(albumAdapter); // EXCLUDED 

// Move the cursor outside of while loop
cursor.close();