android内置数据库的一个错误解决方案:Can't upgrade read-only d...
16lz
2021-01-25
问题焦点:拷贝的内置数据库,在后续的使用时,抛出了Can't upgrade read-only database from version 0 to 1的异常,确定不存在sql错误。
解决方案: 拷贝数据库时,顺便升级下数据的版本信息
这次的android的app开发有个内置数据库的功能,而在此之前,我在本地也通过sql建了一个数据库,为保持兼容性,我只添加了一个是否使用内置数据的功能,使用内置数据库时,只需将apk中的数据库文件覆盖下data/data/<package_name/>下的文件即可,代码如下:
/** * 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 streamInputStream myInput = mContext.getAssets().open(DBConfig.DATABASE_NAME);// Path to the just created empty dbString outFileName = DB_PATH + DBConfig.DATABASE_NAME;// Open the empty db as the output streamOutputStream myOutput = new FileOutputStream(outFileName);// transfer bytes from the inputfile to the outputfilebyte[] buffer = new byte[1024];int length;while ((length = myInput.read(buffer)) > 0) {myOutput.write(buffer, 0, length);}// Close the streamsmyOutput.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());}}我采用这个方法,解决我的问题,希望对大家有帮助。
更多相关文章
- 安卓电子市场开放下载VMware View FOR ANDROID客户端
- Android(安卓)Studio 错误: 编码GBK的不可映射字符;gradle projec
- Android(安卓)Studio项目构建时遇到的常见问题及解决办法
- 使用android studio 版本合并遇到的问题
- 编译 Android(安卓)版本的 Opus 音频编解码库的方法
- [置顶] Android异步加载数据库和多线程编程
- Android(安卓)对象型数据库 db4o
- Android(安卓)Studio 3.5新特性
- Android(安卓)富文本编辑器 图文混排