android – 在SQLiteOpenHelper.onDowngrade()中删除数据库文件的好架构

前端之家收集整理的这篇文章主要介绍了android – 在SQLiteOpenHelper.onDowngrade()中删除数据库文件的好架构前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个基于sqliteOpenHelper的现有数据库,它有几个版本和代码升级它,并且工作正常.但是,如果用户安装了较旧版本的应用程序(需要较低的数据库版本),它将会崩溃 – 使用它的ContentProvider无法访问数据库.我想防止它崩溃,但我不想实际降级数据库添加代码来做这件事会很痛苦.删除所有表肯定会起作用,但从一个新文件开始是更清洁,更不容易出错.

这是关于数据库助手的样子 – 没什么特别的

public class MyDbHelper extends sqliteOpenHelper {
    private static final int DATABASE_VERSION = 3;
    private static final String DATABASE_NAME = "my.db";

    public MyDbHelper(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
    }

    @Override
    public void onCreate(sqliteDatabase db) {
        onUpgrade(db,DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) {
        if (newVersion < 1) db.execsql("CREATE TABLE A...");
        if (newVersion < 2) db.execsql("CREATE TABLE B...");
        if (newVersion < 3) db.execsql("CREATE TABLE C...");
    }

    @Override
    public void onDowngrade(sqliteDatabase db,int newVersion) {
        // I'd like to delete the database here
        // the only problem is that I can't from here
        // since this is called in the middle of getWritableDatabase()
        // and sqliteDatabase has no .recreate() method.
    }
}

我可能采取的方法是:

>从外部执行:捕获ContentProvider中的异常,删除文件并请求再次打开数据库. – 我不喜欢这样,因为它不是提供者的责任.
>用我自己的那个删除文件而不是调用onDowngrade的类的副本替换sqliteOpenHelper – 问题是它使用的是sqliteDatabase的包私有部分(例如.lock()),如果不复制sqliteDatabase我也无法替换它(可能会导致重复整个sqlite堆栈).

有没有什么好方法可以做到这一点,或者我必须采用DROP TABLES方式,例如喜欢描述here

解决方法

我已经找到了一种通过扩展sqliteOpenHelper很好地工作的方法,我在MyDbHelper中需要做的就是扩展这个类.
public abstract class DeletingsqliteOpenHelper extends sqliteOpenHelper {
    private static final String TAG = DeletingsqliteOpenHelper.class.getSimpleName();

    private final File mDatabaseFile;

    public DeletingsqliteOpenHelper(Context context,String name,CursorFactory factory,int version,DatabaseErrorHandler errorHandler) {
        super(context,name,factory,version,errorHandler);
        mDatabaseFile = context.getDatabasePath(name);
    }

    public DeletingsqliteOpenHelper(Context context,int version) {
        super(context,version);
        mDatabaseFile = context.getDatabasePath(name);
    }

    @Override
    public synchronized sqliteDatabase getWritableDatabase() {
        try {
            return super.getWritableDatabase();
        } catch (sqliteDowngradeFailedException e) {
            // that's our notification
        }

        // try to delete the file
        mDatabaseFile.delete()

        // now return a freshly created database
        return super.getWritableDatabase();
    }

    @Override
    public final void onDowngrade(sqliteDatabase db,int newVersion) {
        // throwing a custom Exception to catch it in getWritableDatabase
        throw new sqliteDowngradeFailedException();
    }

    // that's the exception
    static class sqliteDowngradeFailedException extends sqliteException {
        public sqliteDowngradeFailedException() {}

        public sqliteDowngradeFailedException(String error) {
            super(error);
        }
    }
}

猜你在找的Android相关文章