Finalizing a Cursor that has not been deactivated

2019-01-16 10:18发布

i'm getting a "Finalizing a Cursor that has not been deactivated or closed" error on this piece of code. The code is used to fill a listview.

Since it's a non-fatal error , there is no crash and all seems to works fine..but i don't like the error.

If i close the cursor at the end of this code..the listview stay's empty. if i close the cursor in onStop , i get the same error.

How do i fix this??

private void updateList() { 
        DBAdapter db = new DBAdapter(this); 
        db.open(); 
            //load all waiting alarm 
            mCursor=db.getTitles("state<2"); 
            setListAdapter(new MyCursorAdapter(this, mCursor)); 
            registerForContextMenu(getListView()); 
            db.close(); 
        } 


error : 


E/Cursor  ( 2318): Finalizing a Cursor that has not been deactivated 
or closed. database = /data/data/xxxxxxxxxxxxxxx.db, table = alerts, 
query = SELECT _id, alert_id, 
E/Cursor  ( 2318): 
android.database.sqlite.DatabaseObjectNotClosedException: Application 
did not close the cursor or database 
object that was opened here 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDr­iver.java: 
53) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.j­ava: 
1345) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java­: 
1229) 
.... 
.... 

9条回答
Juvenile、少年°
2楼-- · 2019-01-16 10:35

Scott,

I ran into the same problem as you. Before you close your database, i.e. "db.close()," make sure that your cursors are closed first, i.e. "mCursor.close()"

Like so:

private void updateList()
{ 
    DBAdapter db = new DBAdapter(this);
    db.open();

    //load all waiting alarm
    mCursor=db.getTitles("state<2"); 
    setListAdapter(new MyCursorAdapter(this, mCursor)); 
    registerForContextMenu(getListView()); 

    // Let's close the cursor.
    mCursor.close();
    db.close(); 
} 

You mentioned that if you closed your cursor your list view stays empty. I recommend you pass the information over to a class and copy it over (allocate the memory) then close the cursor.

查看更多
Ridiculous、
3楼-- · 2019-01-16 10:35

When a query returns a cursor it is actually positioned "before" the first record in the cursor. An adapter will attempt do a 'getItem' at the first element so it will fail as the cursor is not positioned at any.

In my base adapters I do a cursorMoveToPosition on the getViews. This seems to eliminate the need for the movefirst.

查看更多
对你真心纯属浪费
4楼-- · 2019-01-16 10:40

Just had the same problem and thought to let you know - just in case....

I accidentally called my fetch routine two times and hereby "lost" the resulting cursor of the first call. This caused the error.

查看更多
叼着烟拽天下
5楼-- · 2019-01-16 10:46

Do not use startManagingCursor() since that is no longer the recommended approach. The issue occurs because a cursor / DB connection is still not closed by the time the finalizer gets to this object. You can avoid that by either allowing a loader to manage the cursor or by tracking all cursor / DB / SQLiteOpenHelper connections yourself and cleaning up after them.

Using a Loader is fairly cumbersome and requires a lot of moving parts for it to work in conjunction with say a list view. On the other hand tracking your cursor and database connections is prone to human error. If the number of cursor / DB objects is low, I'd recommend the latter solution. If not, let a loader handle your connections.

查看更多
再贱就再见
6楼-- · 2019-01-16 10:49

startManagingCursor(cursor);

This has fixed my problem

查看更多
【Aperson】
7楼-- · 2019-01-16 10:50

Close the cursor object wherever you are creating it.

When you create a cursor object and done with traversing through a SQLite table then close it after it has been used. This closing of cursor prevents exception in logcat.

You will not get any exception related to finalizing the cursor that left opened.

This fixed same issue in my Application.

查看更多
登录 后发表回答