Java – Do not close cursors or database objects?

Do not close cursors or database objects?… here is a solution to the problem.

Do not close cursors or database objects?

I get this error after attending this activity, start a new activity, and come back. This doesn’t happen when I first load the activity. Functionally everything works fine… But I’m still getting this error.

ERROR/Cursor(1059): Finalizing a
Cursor that has not been deactivated
or closed. database =
/data/data/com.roger.testapp/databases/data,
table = null, query = SELECT MAX(_id)
FROM record

03-02 16:47:21.835:
ERROR/Cursor(1059):
android.database.sqlite.DatabaseObjectNotClosedException:
Application did not close the cursor
or database object that was opened
here

In onCreate:

    mDbHelper = new CommonDbAdapter(this);
    mDbHelper.open();
    fillData();

fillData() calls fetchNote in my dbhelper, the cursor is used for something, if rowId == 0, which means I didn’t select an item to go into this activity, I want to get the last row of that table If rowId = other, then I capture that row. I think the problem is somewhere here, I’m just not sure.

public Cursor fetchNote(long rowId, String table, String columns) throws SQLException {
    if (rowId == 0) {
        String query = "SELECT MAX(_id) FROM record";
        Cursor cursor = mDb.rawQuery(query, null);
        rowId = 0;     
        if (cursor.moveToFirst())
        {               
          rowId = cursor.getInt(0);                         
        }
    }
    Cursor mCursor =
        mDb.query(true, table, new String[] {KEY_ROWID,
                columns}, KEY_ROWID + "=" + rowId, null,
                null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;

}

In onDestroy:

super.onDestroy();
    if (mDbHelper != null) {
        mDbHelper.close();
    }

Also, I’m startManagingCursor

Solution

Do not shut down the database in onDestroy. Close it as soon as it is finished using (make sure to close each cursor before closing the database). onDestroy may not be called when you expect it.

Also, close the Cursor object when you are finished working with it.

Edit:
Since your activity is managing your Cursor, you might consider stopping managing it and closing everything in the onPause method, and opening everything in onResume and fillData again. If you can change your code so that you don’t rely on the activity of managing cursors, then you don’t need to keep open database objects and worry about them.

Related Problems and Solutions