首页 > 代码库 > 数据库版本更新问题

数据库版本更新问题

昨天项目刚发版,测试的时候一切正常,模拟线上更新测试的时候,在模拟下载完新包后安装,出现了闪退现象,当时就吓尿了!。。。

进过一番排查,发现是找不到province表(在新版本开发过程中在数据库手动创建并添加了信息的一个表),但是我明明有把新的数据拷贝进项目,很是奇怪。

先整理下思路:

首先在Application中执行静态代码块,在oncreate()中执行

//初始化数据库CarDatabaseHelper.initDatabase(getApplicationContext());ExtendsDataBase.initPhoneDb(this);// 如果当前的版本号>1,删除旧的的车型库if (Utils.getCurrentVersion(getApplicationContext()) > 1) {ExtendsDataBase.deleteOldDB(getApplication());}

1.0版本后,每次版本更新都会进行数据库的删除和重新写入操作,具体代码如下

package cn.car273.db;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import cn.car273.R;/** * 内置数据库操作文件 *  * @author ... * */public class ExtendsDataBase {    public final static String DATABASE_NAME_OLD = "car273_db.db";    private final static String DATABASE_NAME_NEW = "car273_new.db";    private static ExtendsDataBase _instance;    private static Context context;    private static SQLiteDatabase mDb;    private static String getDBDir() {        return context.getFilesDir().getAbsolutePath()  + File.separator;        //return Utils.getCacheDir(context).getAbsolutePath() + File.separator;    }    private static String getDBPath() {        String path = getDBDir() + DATABASE_NAME_NEW;        return path;    }    /**     * 删除旧的车型库     */    public static void deleteOldDB(Context ctx){        if(context == null){            context = ctx;        }        File oldDb = new File(getDBDir() + DATABASE_NAME_OLD);        if (!oldDb.exists()) {            return;        }        File dirDir = new File(getDBDir());        File[] files = dirDir.listFiles();        for(File f : files){            if (f.getName().contains(DATABASE_NAME_OLD)) {                f.delete();            }        }    }        private static void createPhoneDB() {        File dirFile = new File(getDBPath());        if (dirFile.exists()) {            return;        }        File dirDir = new File(getDBDir());        if (!dirDir.exists()) {            dirDir.mkdirs();        }        try {            InputStream in = ExtendsDataBase.context.getResources().openRawResource(R.raw.car273_db);            File myCaptureFile = new File(getDBPath());            writeToFile(in, myCaptureFile);        } catch (Exception e) {            e.printStackTrace();        }    }    private static void writeToFile(InputStream ins, File file) throws Exception {        OutputStream os = new FileOutputStream(file);        int bytesRead = 0;        byte[] buffer = new byte[8192];        while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {            os.write(buffer, 0, bytesRead);        }        os.close();        ins.close();    }    private ExtendsDataBase() {        mDb = SQLiteDatabase.openOrCreateDatabase(getDBPath(), null);    }        public static ExtendsDataBase getInstance() {        if (_instance == null) {            _instance = new ExtendsDataBase();        }        return _instance;    }    public static void initPhoneDb(Context context) {        ExtendsDataBase.context = context;        ExtendsDataBase.createPhoneDB();    }    public static void close() {        if (ExtendsDataBase.mDb != null && ExtendsDataBase.mDb.isOpen()) {            ExtendsDataBase.mDb.close();        }    }        public SQLiteDatabase getExtendsDB() {        return mDb;    }}

首先initPhoneDb()创建数据库,如果car273_new数据库(car273_db的复制数据库)不存在,则将数据库文件写进输入流,再删除car273_db,再读出输出流得到新的car273_new数据库;如果存在则直接return,不做任何处理。问题就出在了这里!

在升级的前,car273_new和car273_db都是存在的,那就会直接return掉,而不会去执行覆盖操作,所以,需要把红色代码替换成dirFile.delete();即:有需要更新数据库的,直接把旧版本的car273_new删掉,再次复制就可以决绝此问题。

数据库版本更新问题