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(SQLiteDirectCursorDriver.java:
53)
E/Cursor ( 2318): at
android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:
1345)
E/Cursor ( 2318): at
android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:
1229)
....
....
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:
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.
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.
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.
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.
startManagingCursor(cursor);
This has fixed my problem
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.