Home » Android » android – attempt to re-open an already-closed object: SQLiteDatabase:

android – attempt to re-open an already-closed object: SQLiteDatabase:

Posted by: admin June 15, 2020 Leave a comment

Questions:

I’m trying to delete something from a database then insert a new value. I don’t know much about databases, so would appreciate advice on whats going wrong here.

I keep getting the following error:

Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:

Its called from an async task, works fine the first time, but breaks the second time that the task is triggered.

Here are the important snippets:

 public void removeAndInsert(String configRaw) {
    SQLiteDatabase sqlite = null;
    try {
        sqlite = dbHelper.getWritableDatabase();
        removeAndInsert(configRaw, sqlite);
    .....
    finally {
        if (sqlite != null) {
            sqlite.close();
        }
    }



void removeAndInsert(String configRaw, SQLiteDatabase sqlite) throws SQLException {
    ContentValues initialValues = new ContentValues();
    initialValues.put(DBOpenHelper.CONFIG_CACHE_RAW_DATA, configRaw);
    sqlite.delete(DBOpenHelper.CONFIG_CACHE_TABLE_NAME, null, null);
    sqlite.insert(DBOpenHelper.CONFIG_CACHE_TABLE_NAME, null, initialValues);
}
How to&Answers:

Try this.

public void removeAndInsert(String configRaw) {
  SQLiteDatabase sqlite = null;
  try {
    sqlite = dbHelper.getWritableDatabase();
    synchronized(sqlite) {
      removeAndInsert(configRaw, sqlite);
    }
  .....
    finally {
    if (sqlite != null && sqlite.isOpen()) {
        sqlite.close();
    }
}

void removeAndInsert(String configRaw, SQLiteDatabase sqlite) throws SQLException {
  ContentValues initialValues = new ContentValues();
  initialValues.put(DBOpenHelper.CONFIG_CACHE_RAW_DATA, configRaw);
  sqlite.delete(DBOpenHelper.CONFIG_CACHE_TABLE_NAME, null, null);
  sqlite.insert(DBOpenHelper.CONFIG_CACHE_TABLE_NAME, null, initialValues);
}

Answer:

It looks like you’re creating an SQLiteOpenHelper instance (dbHelper) somewhere and getting a writable database from it (sqlite), but then you close the database. If this is the last (or only) database reference that is open, then the entire database will be closed when you call sqlite.close().

You can safely remove the call to sqlite.close() in removeAndInsert(). When your AsyncTask is finished with its database work, call dbHelper.close() to clean up any dangling database references.

Answer:

try to replace sqlite.close(); with dbHelper.close();