Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 372 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Android: Cannot perform this operation because the connection pool has been closed

#1
I was reading through StackOverflow about this question and I still haven't found a solution. I notice that sometimes, my app throws this error:

java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:962)
at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:599)
at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348)
at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894)
...

I have a file called `DatabaseHelper.java` using this approach to get an instance of it:

public static DatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new DatabaseHelper(context.getApplicationContext());
}
return mInstance;
}

Then I have methods like this one (that it crashed in the line `cursor.moveToFirst()` with that error). It almost never crashes, but sometimes it does.

public Profile getProfile(long id) {
SQLiteDatabase db = this.getReadableDatabase();

String selectQuery = "SELECT * FROM " + TABLE_PROFILES + " WHERE " + KEY_PROFILES_ID + " = " + id;
Cursor cursor = db.rawQuery(selectQuery, null);

// looping through all rows and adding to list
Profile profile = new Profile();
if (cursor.moveToFirst()) {
doWhatEver();
}
cursor.close();
db.close();

return profile;
}

So that's it, in all the methods I use:

SQLiteDatabase db = this.getReadableDatabase(); (or Writable)

And then I close the cursor and the db. In this case, the error got throw in the line:

cursor.moveToFirst();

I do not see why the error says the db is closed if I am calling `this.getReadableDatabase()` before. Please support! Thank you :)
Reply

#2
I am having the same problem, have not been able to fix it. I have found a possible clue:
I have a sync thread that is running all the time:


Item ii = dbHelper.popPendingUpload();
if (ii != null)
upload(ii);


And inside DBHelper

public Item popPendingUpload() {

SQLiteDatabase db = getReadableDatabase();
Cursor res = db
.rawQuery("SELECT * FROM items WHERE state = 0 LIMIT 1",
new String[] {});
boolean hasNext = res.moveToFirst();
Item ii = null;
if (hasNext) {
ii = //load item
}
db.close();
return ii;
}

The error also shows up in the moveToFirst() method call. As the thread is poping items out in an infinite loop, the first time it works ok, the second time the error appears. The interesting part is that if I put a breakpoint and step through the code, the error does not show any more. I am testing on a real device using Android 4.1.

I know, is not an answer, but it may help. I'll keep on testing.
Reply

#3
Maybe you close the database before access to database from your app.

You have to edit getProfile() to

public Profile getProfile(long id) {
SQLiteDatabase db = this.getReadableDatabase();

try {
String selectQuery = "SELECT * FROM " + TABLE_PROFILES + " WHERE " + KEY_PROFILES_ID + " = " + id;
Cursor cursor = db.rawQuery(selectQuery, null);

// looping through all rows and adding to list
Profile profile = new Profile();
if (cursor.moveToFirst()) {
doWhatEver();
}
cursor.close();
finally {
db.close();
}
return profile;
}
Reply

#4
//close database after cursor is closed like:

if(cursor.getCount() != 0){

while(cursor.moveToNext()){
//do operation
}
}

cursor.close();
database.close();
Reply

#5
I have a error like yours ,here my code:



try {
String sql = "SELECT * FROM "+DB_TABLEDOWNLOAD;
Cursor cursor = db.rawQuery(sql, null);
//空双引号为原表没有的字段
String temp = "";
int existIconPath = cursor.getColumnIndex("iconPath");
int existAudioID = cursor.getColumnIndex("audioID");

if (existIconPath == -1 && existAudioID == -1){
temp = "url, downed,total,path,name, audioTitle, audioFileID,\"\",\"\"";
}else if (existIconPath == -1 && existAudioID != -1){//iconPath不存在
temp = "url, downed,total,path,name, audioTitle, audioFileID,\"\",audioID";
}else if (existIconPath != -1 && existAudioID == -1){//audioID不存在
temp = "url, downed,total,path,name, audioTitle, audioFileID,iconPath,\"\"";
}else {
return;
}

db.beginTransaction();
String tempTableName = "_temp_"+DB_TABLEDOWNLOAD;
String sqlCreateTemp = " ALTER TABLE "+DB_TABLEDOWNLOAD+" RENAME TO "+tempTableName+";";
db.execSQL(sqlCreateTemp);

final String TB_TESTPAPERINFO_CREATE = "Create TABLE IF NOT EXISTS "
+ DB_TABLEDOWNLOAD
+ "(url TEXT, downed TEXT,total TEXT,path TEXT,name TEXT, audioTitle TEXT, audioFileID TEXT,iconPath TEXT, audioID TEXT);";
db.execSQL(TB_TESTPAPERINFO_CREATE);

String sqlBackupData = "INSERT INTO "+DB_TABLEDOWNLOAD+" SELECT "+temp+" FROM "+tempTableName+";";
db.execSQL(sqlBackupData);
String sqlDrop = "DROP TABLE IF EXISTS '"+tempTableName+"';";
db.execSQL(sqlDrop);
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
}finally{
db.endTransaction();
}


I use return before db.beginTransaction(),my code return before beginTransaction,but I endTransaction in finally . if you do not beginTransaction and endTransaction ,the exception will appear.

so check your code about the db.beginTransaction and endTransaction.
Reply

#6
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()
Reply

#7
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.
Reply

#8
Remove

db.close();

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

The [documentation](

[To see links please register here]

) says:

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

Also, check out

[To see links please register here]

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`.
Reply

#9
Just to mention one more possibility to get this error in case someone searching this post run into the same case:

**Using Database Inspector in Android Studio may cause this error in some situation.**
Reply

#10
I got a similar error message and solved it by removing a db.close() in another activity.

I had a background process for population of a virtual table in one activity and then a db.close() in another activity.

The db.close() didn't do any harm before my long background process ran.

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through