Do not close the cursor or database object?

I get this error after switching to this activity, starting a new one, returning. This does not happen when I load activity first. functionally everything works ... but I still get this error.

ERROR / Cursor (1059): Termination 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: The 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 a couple of things, if rowId == 0, this means that I did not select an element to enter this action, and I want to get the last row in this table. if rowId = something else, then I take this line. I think the problem is here somewhere, 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(); } 

In addition, I run CommandCursor

+4
source share
3 answers

Do not close the database in onDestroy . Close it immediately after using it (make sure that each cursor is closed before closing the database). onDestroy cannot be called when you expect.

Also, close your Cursor object after you finish using it.

edits: Since your activity controls your Cursor , you can consider stopping it and closing everything in the onPause method, and in onResume , open everything again and fillData . If you could change your code so as not to rely on your activities while controlling the cursor, you would not need to keep open database objects and worry about them.

+2
source

I would recommend not returning the cursor. This is a scarce resource.

In n-tier Java EE, it is best practice to close all persistence resources (Connection, Statement, and ResultSet) in the scope of the method in which they were created. Map the ResultSet to an object or collection and close the ResultSet.

I do not know if there is anything special in Android that will make this invalid.

+2
source

Take a look at the activity life cycle - you can see that when you move from your activity ( onPause ), if another activity is required, your process is killed, but when your user returns to activity, it will hit onCreate again. This time you open the NEW CommonDbAdapter (but you never closed the original) - this way, when you end up in onDestroy , you only close the very last mDbHelper.

As pointed out by others, your best method is not to move the cursor from DBHelper, create an object with your data, close the cursor, and pass your object back. Also close DBHelper, as soon as you use it, you can always create another if you need to use it again.

0
source

Source: https://habr.com/ru/post/1342051/


All Articles