正文  数据库 > 数据库/SQLite >

Can't upgrade read-only database from version 0 to 1 android数据库错误

當按下電源鍵,關掉屏幕的時候,再次啟動屏幕。發現老有問題,最後發現原來是需要在AndroidManifest xml裏面設置下:android:configChanges= "orientation|keyboard|keyboardHidden "...

问题焦点:拷贝的内置数据库,在后续的使用时,抛出了 Can't upgrade read-only database from version 0 to 1的异常,确定不存在sql错误。
 
   解决方案: 拷贝数据库时,顺便升级下数据的版本信息
 
 
  这次的android的app开发有个内置数据库的功能,而在此之前,我在本地也通过sql建了一个数据库,为保持兼容性,我只添加了一个是否使用内置数据的功能,使用内置数据库时,只需将apk中的数据库文件覆盖下data/data/下的文件即可,代码如下:
 
/**
* this method should be invoke in another thread except UI thread
* @throws IOException
*/
private void copyDataBase() throws IOException {
MyUtil.log(DBConfig.DB_TAG,
"内置数据库之copyDatabase");
// Open your local db as the input stream
InputStream myInput = mContext.getAssets().open(DBConfig.DATABASE_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DBConfig.DATABASE_NAME;
 
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
 
 
}
 
采用这种方法后,首次调用后,初始化了dbhelper后,倒能正常使用,但从第二次开始,就出现了:
 
SQLiteException: Can't upgrade read-only database from version 1 to 2
 
网上关于这个异常的说法很多,一般是sql语句错误居多,但不适合我的这个场景,我不是初次建数据库,而是使用一个正常内置数据库,首次能读写,就说明 sql不可能有问题的。
 
  对于我的这个异常,跟踪代码,最后发现,原来内置的数据库在拷贝时,并未保存数据库的版本信息,也即版本为0,当第二次初始化sqlitehelper 时,android内部的sqlitehelper便会再次调用oncreate,于是,内置的数据库表已存在,不能再次更新,便抛出了这个异常,知道了原因,就有解决方案了:拷贝数据时,顺带升级下数据库版本即可:
 
public void updateVersion(){
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DBConfig.DATABASE_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
 
 
checkDB.beginTransaction();
int version = checkDB.getVersion();
checkDB.setVersion(DBConfig.DATABASE_VERSION);
checkDB.setTransactionSuccessful();
MyUtil.log(DBConfig.DB_TAG, "修改数据库版本信息  成功");
 
} catch (SQLiteException e) {
// database does't exist yet.
} finally {
if (checkDB != null) {
checkDB.endTransaction();
checkDB.close();
}
}
 
}
 
总的使用方法是:
 
/**
* Creates a empty database on the system and rewrites it with your own
* database.
* you should promise this methods be used only once.
* */
public void createDataBase() throws IOException {
MyUtil.log(DBConfig.DB_TAG, "内置数据库之createDataBase");
//boolean dbExist = checkDataBase();
 
try {
copyDataBase();
MyUtil.log(DBConfig.DB_TAG, "内置数据库之 修改数据库版本信息");
updateVersion();
} catch (IOException e) {
 
throw new Error("Error copying database:" + e.getMessage());
}
 
}
 
我采用这个方法,解决我的问题,希望对大家有帮助