zoukankan      html  css  js  c++  java
  • 数据库版本更新问题

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

    进过一番排查,发现是找不到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删掉,再次复制就可以决绝此问题。

  • 相关阅读:
    L1-045 宇宙无敌大招呼 (5分)
    L1-044 稳赢 (15分)
    L1-043 阅览室 (20分)
    L1-042 日期格式化 (5分)
    L1-041 寻找250 (10分)
    L1-040 最佳情侣身高差 (10分)
    L1-039 古风排版 (20分)
    L1-038 新世界 (5分)
    L1-037 A除以B (10分)
    利用C一种最有效的文件存储方式——16bit有符号位2进制存储
  • 原文地址:https://www.cnblogs.com/ws5861/p/4048746.html
Copyright © 2011-2022 走看看