应用程序崩溃升级SQLite数据库第一次 [英] App crashes upgrading sqlite database first time

查看:821
本文介绍了应用程序崩溃升级SQLite数据库第一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序体验时,SQLite数据库是第一次更新的崩溃。重新加载应用程序,它工作正常,从那时起。我猜这有做的onUpgrade功能即可。我似乎无法找出问题所在,任何意见非常AP preciated。先谢谢了。

DatabaseHelper:

 公共类DatabaseHelper扩展SQLiteOpenHelper {

    私有静态字符串DB_PATH =/data/data/jp.atomicideas.ne/databases/;
    私有静态字符串DB_NAME =数据集;
    公共静态最终诠释DB_VERSION = 2;
    私人SQLiteDatabase MyDatabase的;
    私人最终语境myContext;
    公共静态最后弦乐EX preSSION_TABLE =EX pression;

    / **
     *构造函数
     *注意到并保持传递的上下文中的一个参考,以访问
     *资产和资源。
     *
     * @参数方面
    * /
    公共DatabaseHelper(上下文的背景下){
        超(背景下,DB_NAME,空,DB_VERSION);
        this.myContext =背景;
    }

    / **
     *在系统上创建一个空的数据库,并重写与应用程序数据库
     * @throws IOException异常
    * /
    公共无效的CreateDatabase()抛出IOException异常{
        布尔dbExist = checkDataBase();
        //如果数据库已经存在,做什么
        如果(dbExist){
            Log.v(DB存在,DB存在);
            //这里通过调用这个方法,onUpgrade将被要求可写分贝,如果版本号被撞
            this.getWritableDatabase();
        }
        dbExist = checkDataBase();
        //如果数据库不存在,复制应用程序的数据库中使用
        如果(!dbExist){
            this.getReadableDatabase();
            尝试 {
                copyDataBase();
            }赶上(IOException异常E){
                抛出新的错误(错误复制数据库);
            }
        }
    }

    / **
     *检查数据库已经存在,以避免重新复制文件
     * @返回,只有当它真的存在,如果落在它不
    * /
    私人布尔checkDataBase(){
        SQLiteDatabase CHECKDB = NULL;

        尝试 {
            字符串mypath中= DB_PATH + DB_NAME;
            CHECKDB = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY);
        }赶上(SQLiteException E){
            //数据库还不存在
        }

        如果(CHECKDB!= NULL){
            checkDB.close();
        }

        返回CHECKDB!= NULL?真假;
    }

    / **
     *从本地资产副本数据库文件夹复制到系统文件夹
     * @throws IOException异常
    * /
    私人无效copyDataBase()抛出IOException异常{

        //打开应用程序数据库文件输入流
        InputStream的myInput = myContext.getAssets()开(DB_NAME)。

        //路径向空临时数据库要被替换
        字符串outFileName = DB_PATH + DB_NAME;

        //打开空的数据库文件输出流
        的OutputStream myOutput =新的FileOutputStream(outFileName);

        //将字节从输入文件到输出文件
        byte []的缓冲区=新的字节[1024];
        INT长;
        而((长度= myInput.read(缓冲液))大于0){
            myOutput.write(缓冲液,0,长度);
        }

        //关闭流
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }

    公共无效的openDatabase()抛出的SQLException {

        //打开数据库
        字符串mypath中= DB_PATH + DB_NAME;
        MyDatabase的= SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY);
    }

    @覆盖
    市民同步无效的close(){
        如果(MyDatabase的!= NULL)
            myDataBase.close();
        super.close();
    }

    @覆盖
    公共无效的onCreate(SQLiteDatabase DB){

    }

    @覆盖
    公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){

        Toast.makeText(myContext,onUpgrade叫!,Toast.LENGTH_LONG).show();

        如果(oldVersion<静态网页){
            Log.v(数据库升级,数据库版本更高,升级);
            myContext.deleteDatabase(DB_NAME);
        }
    }

}
 

这里是LogCat中输出:

  06-28 20:52:07.638:V / DB存在(26580):数据库存在
06-28 20:52:07.658:V /数据库升级(26580):数据库版本更高,升级
06-28 20:52:07.658:I /数据库(26580):源码返回:错误code = 1802,味精=声明中止在3:PRAGMA user_version = 2]
06-28 20:52:07.658:E /数据库(26580):执行时失败10(磁盘I / O错误)上0x33a3f0PRAGMA user_version = 2'
06-28 20:52:07.658:I /数据库(26580):源码返回:错误code = 1,MSG =语句中止在2:[ROLLBACK]无法回滚 - 没有事务是有效
06-28 20:52:07.658:E /数据库(26580):失败1(无法回滚 - 没有事务处于活动状态)上执行时0x33a3f0'ROLLBACK;'
06-28 20:52:07.658:D /数据库(26580):回滚过程中的异常,或许pviously执行的DB $ P $自动回滚
06-28 20:52:07.668:D / AndroidRuntime(26580):关闭虚拟机
06-28 20:52:07.668:W / dalvikvm(26580):主题ID = 1:螺纹退出与未捕获的异常(组= 0x2aac8578)
 

  06-28 20:52:07.678:E / AndroidRuntime(26580):android.database.sqlite.SQLiteDiskIOException:产生的原因磁盘I / O错误:PRAGMA user_version = 2
 

解决方案

您不必删除数据库,只需使用你已经alady的方法复制了它定义的( copyDataBase ),像这样的:

  @覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
    Toast.makeText(myContext,onUpgrade叫!,Toast.LENGTH_LONG).show();
    如果(oldVersion<静态网页){
        Log.v(数据库升级,数据库版本更高,升级);
        尝试 {
            copyDataBase();
        }赶上(IOException异常E){
            抛出新的错误(错误升级数据库);
        }
    }
}
 

my app experiences a crash when the sqlite database is updated the first time. Reloading the app, it works fine from then on. I'm guessing this has to do with the onUpgrade function then. I can't seem to locate where the problem is, any advice very appreciated. Thanks in advance.

DatabaseHelper:

public class DatabaseHelper extends SQLiteOpenHelper {

    private static String DB_PATH = "/data/data/jp.atomicideas.ne/databases/";
    private static String DB_NAME = "dataset";
    public static final int DB_VERSION = 2;
    private SQLiteDatabase myDataBase;
    private final Context myContext;
    public static final String EXPRESSION_TABLE = "expression";

    /**
     * Constructor
     * Takes and keeps a reference of the passed context in order to access
     * the assets and resources.
     * 
     * @param context
    */
    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.myContext = context;
    }

    /**
     * Creates an empty database on the system and rewrites with database from app
     * @throws IOException
    */
    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();  
        // if the database already exists, do nothing
        if(dbExist){
            Log.v("DB Exists", "db exists");
            // by calling this method here, onUpgrade will be called on a writeable db, if version number is bumped
            this.getWritableDatabase();
        } 
        dbExist = checkDataBase();
        // if the database doesn't exist, copy the application's database to be used
        if(!dbExist) {
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    /**
     * Check if the database already exists to avoid re-copying the file
     * @return true only if it exists, falls if it doesnt
    */
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;

        try {
            String mypath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READONLY);
        } catch(SQLiteException e) {
            // database does not exist yet
        }

        if(checkDB != null) {
            checkDB.close();
        }

        return checkDB != null ? true : false;
    }

    /**
     * Copies database from the local assets folder to the system folder
     * @throws IOException
    */
    private void copyDataBase() throws IOException {

        // Open the app database file as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        // Path to the empty temporary database to be replaced
        String outFileName = DB_PATH + DB_NAME;

        // Open the empty database file as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        // Transfer bytes from the input file to the output file
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        // Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }

    public void openDataBase() throws SQLException {

        // Open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }

    @Override
    public synchronized void close() {
        if(myDataBase != null)
            myDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        Toast.makeText(myContext, "onUpgrade called!", Toast.LENGTH_LONG).show();

        if (oldVersion < newVersion) {
            Log.v("Database Upgrade", "Database version higher, upgrading");
            myContext.deleteDatabase(DB_NAME);                          
        }
    }

}

And here is the LogCat output:

06-28 20:52:07.638: V/DB Exists(26580): db exists
06-28 20:52:07.658: V/Database Upgrade(26580): Database version higher, upgrading
06-28 20:52:07.658: I/Database(26580): sqlite returned: error code = 1802, msg = statement aborts at 3: [PRAGMA user_version = 2] 
06-28 20:52:07.658: E/Database(26580): Failure 10 (disk I/O error) on 0x33a3f0 when executing 'PRAGMA user_version = 2'
06-28 20:52:07.658: I/Database(26580): sqlite returned: error code = 1, msg = statement aborts at 2: [ROLLBACK;] cannot rollback - no transaction is active
06-28 20:52:07.658: E/Database(26580): Failure 1 (cannot rollback - no transaction is active) on 0x33a3f0 when executing 'ROLLBACK;'
06-28 20:52:07.658: D/Database(26580): exception during rollback, maybe the DB previously performed an auto-rollback
06-28 20:52:07.668: D/AndroidRuntime(26580): Shutting down VM
06-28 20:52:07.668: W/dalvikvm(26580): threadid=1: thread exiting with uncaught exception (group=0x2aac8578)

AND

06-28 20:52:07.678: E/AndroidRuntime(26580): Caused by: android.database.sqlite.SQLiteDiskIOException: disk I/O error: PRAGMA user_version = 2

解决方案

You don't need to delete the database, just copy over it using the method you've alady defined (copyDataBase), like this:

@Override  
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
    Toast.makeText(myContext, "onUpgrade called!", Toast.LENGTH_LONG).show();  
    if (oldVersion < newVersion) {  
        Log.v("Database Upgrade", "Database version higher, upgrading");  
        try { 
            copyDataBase(); 
        } catch (IOException e) { 
            throw new Error("Error upgrading database"); 
        } 
    } 
}  

这篇关于应用程序崩溃升级SQLite数据库第一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆