【问题标题】:Android database - Cannot perform this operation because the connection pool has been closedAndroid 数据库 - 无法执行此操作,因为连接池已关闭
【发布时间】:2014-06-16 17:36:13
【问题描述】:

我对 android 数据库和游标有奇怪的问题。有时(很少)会发生,我收到客户的崩溃报告。很难找出它崩溃的原因,因为我有大约 150 000 个活跃用户,并且每周可能有 1 个报告左右,所以这确实是一些小错误。这是一个例外:

STACK_TRACE=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)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at sk.mildev84.agendareminder.a.c.a(SourceFile:169)

在每个光标“迭代和探索”之前,我使用这段代码来确保一切正常:

db = instance.getWritableDatabase();
cursor = db.rawQuery(selectQuery, null);

if (isCursorEmptyOrNotPrepared(cursor)) {
    ...
    }

private synchronized boolean isCursorEmptyOrNotPrepared(Cursor cursor) {
        if (cursor == null)
            return true;

        if (cursor.isClosed())
            return true;

        if (cursor.getCount() == 0) // HERE IT CRASHES
            return true;

        return false;
    }

它落在以下行:

if (cursor.getCount() == 0)

有人知道为什么吗?我想,我正在检查所有可能的异常和条件...为什么我的应用程序在这里崩溃?

PS:所有数据库方法都是同步的,我在所有情况下都正确打开和关闭数据库/游标,我检查了很多次。

【问题讨论】:

  • 发布更多代码和完整的堆栈跟踪。你得到这个异常 -> 你在某个地方有错误
  • 不需要关闭数据库。安卓处理。在这里阅读这个很好的解释...stackoverflow.com/questions/14002022/…
  • @Nepster 我想知道这是否仅适用于内容提供者
  • 请问您是如何解决这个错误的?请让我知道@GuriBhai 解决方案是否适合您。我遇到了同样的错误,但关闭数据库并没有解决我的问题。

标签: android database android-cursor


【解决方案1】:

问题
如果你在关闭数据库后尝试另一个操作,它会给你这个异常。因为db.close();释放了对该对象的引用,如果最后一个引用被释放,则关闭该对象。

解决方案
在静态上下文中保留一个 SQLiteOpenHelper 实例(Singleton)。做延迟初始化,然后synchronize那个方法。比如

public class DatabaseHelper
{
    private static DatabaseHelper instance;

    public static synchronized DatabaseHelper getInstance(Context context)
    {
        if (instance == null)
            instance = new DatabaseHelper(context);

        return instance;
    }
//Other stuff... 
}

并且您不必关闭它吗?当应用程序关闭时,它会释放文件引用,如果它甚至持有它
即您不应该关闭数据库,因为它将在下一次调用中再次使用。 所以只需删除

db.close();

欲了解更多信息,请参阅Single SQLite connection

【讨论】:

    【解决方案2】:

    问题很明显

    SQLiteCursor 无法执行 'getCount' 操作,因为连接池已关闭

    为了避免 IllegalStateException,如果合适的话,我们可能会一直保持数据库打开。在其他情况下,我们需要在尝试 getCount 之前检查状态

    我的经验如下:

    有缺陷的代码:

    SOLiteOpenHelper helper = new SOLiteOpenHelper(context);
    SQLiteDatabase db = helper.getWritableDatabase();
    Cursor cursor = db.query(...);
    if (cursor != null) {
        cursor.getCount(); // HERE IT CRASHES
    }
    

    完美代码:

    SOLiteOpenHelper helper = new SOLiteOpenHelper(context);
    SQLiteDatabase db = helper.getWritableDatabase();
    Cursor cursor = db.query(...);
    if (cursor != null && db.isOpen()) {
        cursor.getCount(); // OK!
    }
    

    【讨论】:

      【解决方案3】:

      您只需删除 删除 db.close()

      【讨论】:

        【解决方案4】:

        我也有这个问题。我的 SQLiteOpenHelper 类是 Singleton 以及在每次 CRUD 操作后关闭数据库。 在我的 SQLiteOpenHelper 类中同步我的方法(CRUD)后,我不再收到错误:)

        【讨论】:

          【解决方案5】:

          同样的问题发生在我身上,所以在阅读explanation后我删除了
          db.close();
          来自
          public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

          public int delete(Uri uri, String selection, String[] selectionArgs)
          ContentProvider 的方法
          不需要 db.close(),因为 ContentProvider 自己负责关闭数据库。

          【讨论】:

            猜你喜欢
            • 2015-02-27
            • 2015-07-12
            • 2013-04-10
            • 1970-01-01
            • 2016-02-11
            • 2013-02-05
            • 1970-01-01
            • 1970-01-01
            • 2017-04-23
            相关资源
            最近更新 更多