Android : android database update java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

on Monday, July 14, 2014


I want to update my sqlite database when I update the android app into new version,but there happen a problem as title. this is my code:



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


the class AxtDataBaseHelper method implement as:



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;

}


when code run into onUpgrade at TableUtils.dropTable(connectionSource, AXTClazzRecord.class, true); have a problem ,the log is:



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)


note : code run order is @1-> @2-> @3

anybody can help me?


0 comments:

Post a Comment