2

我发布了我的应用程序的更新,并从用户那里收到大量错误,我无法重新创建它或查明问题。

我得到两个错误: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

java.lang.IllegalStateException: database not open

错误发生在以下代码中的某处:

public DBUserC getUser(int _id){
        synchronized (DBAdapter.LOCK){
            M.openDB(context);
            Cursor cursor = M.database.query(DBUserHelper.TABLE_USERS,
                    VUser.allColumns, DBUserHelper.COLUMN_ID + " = '"+_id+"'", null, null, null, null);
            DBUserC user;
            if (cursor.moveToFirst()){
                user = cursorToInfo(cursor);
            } else{
                user = newUser();
            }
            cursor.close();
            M.closeDB();
            return user;
        }
        }

在这个版本中,有一个数据库升级,其中我通过db.execSql. 它不在单独的线程中。

在每次调用数据库时(除了在 中onUpgrade),我同步,然后打开它,运行我的代码,然后关闭它。在此升级之前我没有任何问题,并且找不到问题。

任何帮助将不胜感激。

编辑:要打开我的数据库,我会:

if (helper==null)
    helper = new DBAdapter(context);
if (database==null){
     database = helper.getWritableDatabase();
} else if (!database.isOpen())
     database = helper.getWritableDatabase();

并关闭:

helper.close();
helper = null;
database = null;

获取信息的示例方法:

    public DBUserC getUser(int _id){
        synchronized (DBAdapter.LOCK){
            openDB(context);//this is the open code above
            Cursor cursor = M.database.query(DBUserHelper.TABLE_USERS,
                    VUser.allColumns, DBUserHelper.COLUMN_ID + " = '"+_id+"'", null, null, null, null);
            DBUserC user;
            if (cursor.moveToFirst()){
                user = cursorToInfo(cursor);//does not contain DB operations
            } else{
                user = newUser(); ////does not contain Database operations
            }
            cursor.close();
            closeDB();//This is the close code above
            return user;
        }
    }

AHost.onCreate

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        M.initializeDB(context); //synchronized call to the openDB code I posted above
        M.openDataDB(context); //opens a different database by a different file name. This DB is not an issue

        //irrelevant ui setup
        int _id = pref.getInt(P.eLastUser, VUser.ID_NEW);//row id of user

        M.requeryUser();//synchronized, access database
        M.switchUser(_id);//synchronized, access database

    }
4

3 回答 3

1

我在我的一个应用程序中遇到了同样的问题,我如何解决这个问题是通过删除 cursor.close()。希望它会有所帮助:)

于 2014-01-21T08:48:42.653 回答
0

我无法重新创建问题,因为在测试中,我正在从 DB 版本 3 升级到版本 4。我的许多用户正在从版本 2 升级到版本 4。从 2 升级到 3 的一些代码是基于方法的。我最终更改了版本 4 的一些方法,这破坏了版本 3 的升级。然后我从我拥有的 cursorToObject() 方法中得到一个捕获的异常,这导致 database.close 被跳过,然后我得到了 sqlite 异常

于 2014-01-18T08:41:49.307 回答
0

显然,我们需要看到 on-upgrade 方法似乎是您问题的根本原因。我使用我发现它的博客命名的亚当斯升级方法。

注意:每次升级都在 upgradeTo <= newVersion 循环中完成。也许有一天我会在这个循环上放一个进度条。

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    int upgradeTo = oldVersion + 1;
    while (upgradeTo <= newVersion) {
        switch (upgradeTo) {
        // update old resrawid's to constants
        // this was caused when I saved R values in the database
        // and then later realized they would change.
        // the old resrawid is changed to a constant.
        case 42:
            ContentValues values;
            @SuppressWarnings("unused")
            // used for debugging so I can see the value of the update.
            int res;
            int rs;
            rs = 2130968576;
            values = new ContentValues();
            values.put(
                    KEY_RESRAWID,
                    com.gosylvester.bestrides.ImageTextListViewActivity.SAMPLE_DRAGON);
            res = db.update(TABLE_RIDES, values, KEY_RESRAWID + " = ?",
                    new String[] { String.valueOf(rs) });

            rs = 2130968577;
            values = new ContentValues();
            values.put(
                    KEY_RESRAWID,
                    com.gosylvester.bestrides.ImageTextListViewActivity.SAMPLE_M119);
            res = db.update(TABLE_RIDES, values, KEY_RESRAWID + " = ?",
                    new String[] { String.valueOf(rs) });

            rs = 2130968578;
            values = new ContentValues();
            values.put(
                    KEY_RESRAWID,
                    com.gosylvester.bestrides.ImageTextListViewActivity.SAMPLE_MEDINA);
            res = db.update(TABLE_RIDES, values, KEY_RESRAWID + " = ?",
                    new String[] { String.valueOf(rs) });
            break;
        case 43:
            // new column added for last_viewed.
            db.execSQL(VERSION_43_ALTER);
            break;

        case 44:
            // new index on KEY_DATE_UPDATE DESC
            db.execSQL(VERSION_44_CREATE_INDEX);
        }
        upgradeTo++;
    }
}

祝你好运丹尼117

于 2014-01-22T22:27:35.677 回答