數據庫版本更新問題

昨天項目剛發版,測試的時候一切正常,模擬線上更新測試的時候,在模擬下載完新包後安裝,出現了閃退現象,當時就嚇尿了!。。。java

進過一番排查,發現是找不到province表(在新版本開發過程當中在數據庫手動建立並添加了信息的一個表),可是我明明有把新的數據拷貝進項目,非常奇怪。android

先整理下思路:sql

首先在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,不作任何處理。問題就出在了這裏!this

在升級的前,car273_new和car273_db都是存在的,那就會直接return掉,而不會去執行覆蓋操做,因此,須要把紅色代碼替換成dirFile.delete();即:有須要更新數據庫的,直接把舊版本的car273_new刪掉,再次複製就能夠決絕此問題。spa

相關文章
相關標籤/搜索