数据库版本更新问题

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

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

时间: 2024-10-14 00:40:34

数据库版本更新问题的相关文章

Android Sqlite 数据库版本更新

http://87426628.blog.163.com/blog/static/6069361820131069485844/ 1.自己写一个类继承自SqliteOpenHelper 2.会实现SqliteOpenHelper的两个方法 onCreate与onUpgrade,google文档对两个回调方法的解释是创建数据库的时候调用与更新数据库的版本的时候调用 3.Sqlite数据库主要是用来缓存应用的数据,而应用却是一直在更新版本,相应的数据的表的字段也会一直增加会改变或减少 4.这个时候就

使用SQLiteOpenHelper操控数据库

上次我使用SQLiteDatabase来操作数据库,但更常见的是使用SQLiteDatabase来操作SQLite. 一般的用法是创建SQLiteOPenHelper的子类,扩展它的onCreatea(SQLiteDatabase db) 和 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法. Synchronized SQLiteDatabase getReadableDatabase() -->以读写的方式打开数据库

Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())

数据库版本升级对软件的管理操作. 我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新. 数据库版本更新需要主要的问题: 软件的1.0版本升级到1.1版本时,老的数据不能丢. 那么在1.1版本的程序中就要有地方能够检测出来新的软件版本与老的数据库不兼容,并且能够有办法把1.0软件的数据库升级到1.1软件能够使用的数据库. 换句话说,要在1.0软件的数据库的那个表中增加那个字段,并赋予这个字段默认值. 当然有的时候我们对更新后的 版本并没有什么好感,

html5本地存储(三)--- 本地数据库 indexedDB

html5内置了2种本地数据库,一是被称为"SQLLite",可以通过SQL语言来访问文件型SQL数据库.二是被称为"indexedDB" 的NoSQL类型的数据库,本篇主要讲indexedDB数据库. 该数据库是一种存储在客户端本地的NoSQL数据库,目前chrome11以上.Firefox4以上.Opera18以上.Safar8以上及IE10以上的浏览器提供支持 一.连接数据库 使用indexedDB.open方法连接数据库 var dbName = 'inde

Anroid 数据库的创建

创建数据库首先要了解SQLiteOpenHelper类 1.构造方法 public SQLiteOpenHelper(Context context,String name, SQLiteDatabase.CursorFactory factory, int version); 2.创建数据库时调用的方法 public void onCreate(SQLiteDataBase db); 执行一条带占位符的SQL语句,提高预编译的速度 public void execSQL(String sql,

Android中SQLite数据库的简单使用

File file = new File("hah.txt"); //只是创建了一个对象file, file指向了hah.txt这个文件,hah.txt这个文件可能存在,也可能不存在.如果文件不存在,则不会被创建. 必须要有文件输出流对文件进行了写的操作,文件才会被创建. 游标:在访问数据库中表结构时,想访问表中的某一行的时候,数据库内部有一个快速的定位方式,这个定位方式是通过索引来实现的.游标相当于数组的指针,通过游标的上下移动来查找数据. 在Android中使用SQLite数据库,

Android开发之SQLite数据库详解

Android开发之SQLite数据库详解 请尊重他人的劳动成果,转载请注明出处:Android开发之SQLite数据库详解 http://blog.csdn.net/fengyuzhengfan/article/details/40194393 Android系统集成了一个轻量级的数据库:SQLite, SQLite并不想成为像Oracle.MySQL那样的专业数据库.SQLite只是一个嵌入式的数据库引擎,专门适用于资源有限的设备上(如手机.PDA等)适量数据存取. 虽然SQLite支持绝大

android数据库(随apk一起发布数据库)

读取数据库+数据库版本更新 注意: a, 将随apk发布的数据库放在android工程下/res/raw路径下. b, 数据库文件存到手机上时,路径在/data/data/你的包名/databases下,其他路径则会出错. 需要直接在工程里新建数据库时,会继承SQLiteOpenHelper,但本文讲的是随apk一起发布数据库的情况,因此没有必要继承SQLiteOpenHelper,但也需要对test.db做一层包装,在对test.db进行包装的类对数据库进行操作. 编写程序的过程中经常改变数据

【Anroid进阶】SQLite数据库使用完全详解

在Android开发中,我们一般可以使用文件.sharedpreferences.以及数据库来保存我们程序运行中产生的数据,本篇主要讲解如何使用SQLite数据库,完成数据的增删改查的一般操作 SQLite介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它. SQLite 和其他的主要 SQL 数据库没什么区别.它的优点就是高效,Android 运行时环境包含了完整的 SQLite. SQLite 和其他