Android: Cannot perform this operation because the connection pool has been closed Android: Cannot perform this operation because the connection pool has been closed java java

Android: Cannot perform this operation because the connection pool has been closed


Remove

db.close();

If you try another operation after closing the database, it will give you that exception.

The documentation says:

Releases a reference to the object, closing the object...

Also, check outAndroid SQLite closed exception about a comment from an Android Framework engineer which states that it is not necessary to close the database connection, however this is only when it is managed in a ContentProvider.


I currently have the same problem. While removing the db.close() solves the issue for me, I think the issue is caused by multi-threading. Here is my research.

SQLiteOpenHelper holds a reference to SQLiteDatabase, when getReadableDatabase() or getWritableDatabase() called, it will return the reference, if the SQLiteDatabase is closed or null, a new SQLiteDatabase object will be created. Note that inside the get method, codes are guarded in a synchronized block.

SQLiteDatabase is a subclass of SQLiteClosable. SQLiteClosable implements a reference counting scheme.

  • When first created, the count is 1.

  • When the database operation methods run (like insert, query), it will increase the count, and decrease the count when methods end. But the cursor operations are NOT protected by reference counting.

  • If the count decreases to 0, connection pool will be closed and a member SQLiteConnectionPool object will be set to null, and now the SQLiteDatabase is closed;

  • SQLiteDatabase.close() will decrease the count by 1;

So, if you have a single-threaded scheme, closing the SQLiteDatabase will be fine because SQLiteOpenHelper will just re-recreate it.

If you do multi-threading, then you will run into trouble. Say thread A and thread B both call getReadableDatabase(), and SQLiteOpenHelper returns the SQLiteDatabase it holds, and then thread A first finished its operation and call SQLiteDatabase.close(), now the SQLiteDatabase object thread B has is closed so any subsequent db operation calls or cursor method calls will throw the exception.


This is a simple error in Android architecture initialisation of room database with getApplicationContext(), this means that your application has one instance of the database reference, no matter how many activities create an instance of it, therefore if you close it in any activity the others will throw that exception.

Essentially don't just check the activity throwing the exception but every activity for db.close()