Android的数据库 - 因为连接池已关闭,无法执行此操作 [英] Android database - Cannot perform this operation because the connection pool has been closed

查看:5148
本文介绍了Android的数据库 - 因为连接池已关闭,无法执行此操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有Android的数据库和游标奇怪的问题。每隔一段时间(很少)发生时,我得到来自客户的故障报告。很难找出为什么它崩溃,因为我有150〜000的活跃用户,也许每周1报告左右,所以它是真正的一些小bug。这里是例外:

I have strange problem with android database and cursors. Time to time (very rarely) happens, that I got crash report from customers. It's hard to find out why it crashes, as I have ~ 150 000 active users and maybe 1 report per week or so, so it's really some minor bug. Here is exception:

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)

每个光标迭代和探索我用这个code,以确保一切正常之前:

Before every cursor "iterating and exploring" I use this code to make sure everything is ok:

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)

任何人都知道为什么吗?我想,我检查所有可能出现的异常和条件...为什么我的应用程序崩溃吗?

Anyone know why? I think, I am checking all possible exceptions and conditions...Why is my app crashing here?

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

PS: All database methods are synchronized and I am correctly opening and closing database/cursors in all cases, I checked it many times.

推荐答案

问题

如果您关闭数据库后,尝试另一种操作,它会给你exception.Because db.close(); 释放到对象的引用,关闭对象,如果最后参考被释放。
解决方案

保持一个 SQLiteOpenHelper 实例(辛格尔顿),在静态情况下。不要延迟初始化,而同步该方法。如

Problem
If you try another operation after closing the database, it will give you that exception.Because db.close(); releases a reference to the object, closing the object if the last reference was released. Solution
Keep a single SQLiteOpenHelper instance(Singleton) in a static context. Do lazy initialization, and synchronize that method. Such as

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... 
}

您不必将其关闭?当应用程序关闭时,它会放手的文件引用的,如果连抱着它


即你不应该关闭数据库,因为它将在下次调用再次使用。
所以才删除

And you don't have to close it? When the app shuts down, it’ll let go of the file reference, if its even holding on to it.
i.e. You should not close the DB since it will be used again in the next call. So Just remove

db.close();

有关更多信息,请参见在单SQLite的连接

For more info See at Single SQLite connection

这篇关于Android的数据库 - 因为连接池已关闭,无法执行此操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆