问题焦点:拷贝的内置数据库,在后续的使用时,抛出了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());}}
我采用这个方法,解决我的问题,希望对大家有帮助。

更多相关文章

  1. 安卓电子市场开放下载VMware View FOR ANDROID客户端
  2. Android(安卓)Studio 错误: 编码GBK的不可映射字符;gradle projec
  3. Android(安卓)Studio项目构建时遇到的常见问题及解决办法
  4. 使用android studio 版本合并遇到的问题
  5. 编译 Android(安卓)版本的 Opus 音频编解码库的方法
  6. [置顶] Android异步加载数据库和多线程编程
  7. Android(安卓)对象型数据库 db4o
  8. Android(安卓)Studio 3.5新特性
  9. Android(安卓)富文本编辑器 图文混排

随机推荐

  1. Android编译过程详解(二)
  2. Android菜单详解——理解android中的Menu
  3. TableLayout常用细节
  4. Android(安卓)横竖屏总结
  5. [Android(安卓)UI] Activity Maintheme (
  6. android电池系统
  7. Android横竖屏总结
  8. AndroidManifest.xml文件详解(data)
  9. Android(安卓)SDK 国内镜像
  10. flutter [!] Android(安卓)toolchain - d