【问题标题】:attempt to re-open an already-closed object: SQLiteDatabase:尝试重新打开一个已经关闭的对象:SQLiteDatabase:
【发布时间】:2013-09-26 17:09:18
【问题描述】:

我正在尝试从数据库中删除某些内容,然后插入一个新值。我对数据库知之甚少,因此希望就这里出了什么问题提出建议。

我不断收到以下错误:

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

它从异步任务调用,第一次工作正常,但第二次触发任务时中断。

这里是重要的sn-ps:

 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);
}

【问题讨论】:

  • 这部分代码看起来不错,您是否在代码中的其他地方关闭?例如你的 dbHelper 类?
  • 好的,我发现了问题,似乎应用程序中的其他地方正在另一个线程上打开和关闭数据库!
  • @serenskye 请编辑您的问题(或发布答案)以包含您的解决方案的详细信息。

标签: android sqlite


【解决方案1】:

试试这个。

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);
}

【讨论】:

  • 结束行没有出现错误,第二次使用removeAndInsert时出现问题
  • @serenskye 我更改了上面的示例以包括同步对数据库对象的调用。
  • 同步(值)?它是什么?,异步任务?
  • 我使用了方法 public synchronized void insert() //form correct... 但这个解决方案不起作用,我从未使用过 synchronized(sqlite) // 从不
  • isOpen():方法 isOpen() 未为 SQLLiteAdapter 类型定义。我无法在列表中找到该方法。
【解决方案2】:

看起来您正在某处创建 SQLiteOpenHelper 实例 (dbHelper) 并从中获取可写数据库 (sqlite),但随后您关闭了数据库。如果这是最后一个(或唯一一个)打开的数据库引用,那么当您调用 sqlite.close() 时,整个数据库将被关闭。

您可以安全地删除对removeAndInsert() 中的sqlite.close() 的调用。当您的 AsyncTask 完成其数据库工作后,调用 dbHelper.close() 以清理任何悬空的数据库引用。

【讨论】:

  • 在调用 close 的地方移动,不会改变结果
  • 您的应用程序必须在其他地方关闭数据库,然后,正如@Guru 指出的那样。没有看到更多代码,我们只能推测问题的根源。
【解决方案3】:

尝试将sqlite.close(); 替换为dbHelper.close();

【讨论】:

    猜你喜欢
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多