android database update java.lang.IllegalStateException:尝试重新打开一个已经关闭的对象:SQLiteDatabase

时间:2014-07-15 05:17:48

标签: android sqlite ormlite

当我将Android应用程序更新为新版本时,我想更新我的sqlite数据库,但是出现了标题问题。这是我的代码:

String dbname="AXT_"+role+"_"+user.id+".db";
dh=AxtDataBaseHelper.getInstance(dbname, R.raw.axt_init);
Dao<AXTUser, String> dao;
try {
    dao = dh.getDao(AXTUser.class);
     //@2
    dao.createOrUpdate(user);
} catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

类AxtDataBaseHelper方法实现为:

public class AxtDataBaseHelper extends DatabaseHelper {
private final String databaseName;
private static String targetDbName;
//获取数据库的版本号,全局
private static final int AXT_DATABASE_VERSION = 2;

//每个DatabaseHelpershi,数据库名----数据库----DatabaseHelper实例,这三者是一对一的关系
private static HashMap<String, DatabaseHelper> helperes = new HashMap<String, DatabaseHelper>();

//数据库名创建helper
private AxtDataBaseHelper(String databaseName) {
    super(databaseName, AXT_DATABASE_VERSION);
    this.databaseName = databaseName;
}

/**
 * 无种子数据库的方式,单例
 */
public static synchronized DatabaseHelper getInstance(String databaseName) {
    DatabaseHelper helper = helperes.get(databaseName);
    if (helper == null) {
        helper = new AxtDataBaseHelper(databaseName);
        helperes.put(databaseName, helper);
    }
    return helper;
}
/**
 * 有种子数据库的方式,单例。需要种子数据库的raw resource id
 */
@1
public static synchronized DatabaseHelper getInstance(String databaseName, int seedDbRawResId) {
    DatabaseHelper helper = helperes.get(databaseName);
    String targetDbDir = CommonApplication.getAppDatabasePath();
    IOUtil.makedirs(targetDbDir);
    targetDbName = CommonApplication.getAppDatabasePath() + File.separator + databaseName;
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(targetDbName, null);
    Log.e("创建时数据库version ", db.getVersion() + ",1-onCreate[" + databaseName + "]");
    //此helper目前使用“数据直接替换”的方式升级
    //targetDb 不存在表结构 则释放种子数据库
    if (!tabIsExist(db, databaseName, "AXTUser")) {
        //将种子数据库释放出来
        IOUtil.releaseRawToFile(seedDbRawResId, CommonApplication.getAppDatabasePath(), databaseName);
        //再次打开,并将当前version设置到目标数据库中
        db = SQLiteDatabase.openDatabase(targetDbName, null, SQLiteDatabase.OPEN_READWRITE);
        db.setVersion(AXT_DATABASE_VERSION);
        Log.e("释放种子数据库version ", db.getVersion() + ",2-onCreate[" + databaseName + "]");
    } else {
        Log.e("数据库获取已存在数据库", "数据库获取已存在数据库");
        if (db.getVersion() < AXT_DATABASE_VERSION) {
            Log.e("数据库升级", "数据库将要升级");
            db.needUpgrade(AXT_DATABASE_VERSION);
        }
    }
    db.close();
    db.releaseReference();
    Log.e("数据库升级已关闭", "数据库升级已关闭");
    helper = new AxtDataBaseHelper(databaseName);
    helperes.put(databaseName, helper);
    return helper;
}

@Override
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
}

@3
@Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
    Log.e("数据库升级", "数据库执行升级");
    int oldVertion = db.getVersion();
    for (int j = oldVertion; j <= AXT_DATABASE_VERSION; j++) {
        switch (j) {
            case 2 :
                Log.e("数据库升级", "from: " + oldVertion + " to: " + j);
                try {
                    connectionSource.isOpen();
                    db.isOpen();
                    //删除旧表
                    TableUtils.dropTable(connectionSource, AXTClazzRecord.class, true);
                    //创建新表
                    TableUtils.createTableIfNotExists(connectionSource, AXTClazzAttendences.class);
                    TableUtils.createTableIfNotExists(connectionSource, AXTClazzRecord.class);
                    TableUtils.createTableIfNotExists(connectionSource, AXTClazzResources.class);
                    Log.e("数据库升级", "数据库升级执行成功");
                } catch (Exception e) {
                    Log.e("数据库升级异常", "数据库升级异常");
                    e.printStackTrace();
                } finally {
                    db.close();
                }
                break;
        }
    }
}
public String toString() {
    return "db=" + databaseName + "; version=" + AXT_DATABASE_VERSION;

}

当代码在onUpgrade TableUtils.dropTable(connectionSource, AXTClazzRecord.class, true);遇到问题时,日志为:

07-15 13:09:31.299: E/AndroidRuntime(10283): java.lang.RuntimeException: Unable to create application com.alo7.axt.AxtApplication: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.alo7.axt/databases/AXT_1_204.db
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4521)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.app.ActivityThread.access$1500(ActivityThread.java:157)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.os.Handler.dispatchMessage(Handler.java:102)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.os.Looper.loop(Looper.java:157)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.app.ActivityThread.main(ActivityThread.java:5293)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at java.lang.reflect.Method.invokeNative(Native Method)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at java.lang.reflect.Method.invoke(Method.java:515)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at dalvik.system.NativeStart.main(Native Method)
07-15 13:09:31.299: E/AndroidRuntime(10283): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.alo7.axt/databases/AXT_1_204.db
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:522)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:263)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at com.j256.ormlite.android.AndroidConnectionSource.getReadWriteConnection(AndroidConnectionSource.java:66)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at com.j256.ormlite.android.AndroidConnectionSource.getReadOnlyConnection(AndroidConnectionSource.java:54)
07-15 13:09:31.299: E/AndroidRuntime(10283):    at com.j256.ormlite.dao.BaseDaoImpl.idExists(BaseDaoImpl.java:805)

注意:代码运行顺序是@ 1-&gt; @ 2→ @ 3
有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:0)

在进行任何事务之前使用以下方法打开数据库: - yourdatabase_instance.open()然后关闭与yourdatabase_instance.close()关联。您收到此错误是因为您尝试更新数据库但未打开与数据库的连接。