首页 > 解决方案 > 如何防止 SQLiteOpenHelper 上的应用程序崩溃 onUpgrade 失败

问题描述

如果在我的扩展 SQLiteOpenHelper 类的 onUpgrade 方法中出现错误,应用程序就会崩溃。我宁愿让应用程序继续打开数据库并禁用某些依赖于新模式的功能。

我实现它如下,但觉得这有点令人费解。有谁知道让我的应用程序在数据库升级失败时继续运行的更受支持或更好的方法?

DBHelper 类:

class DBHelper extends SQLiteOpenHelper {
    public int _actual_version = 0;

    public DBHelper(Context context) {
        super(context, "example_db_name", null, 2);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        this._actual_version = oldVersion;

        try {
            //do some upgrade code

            this._actual_version = newVersion;
        } catch (Throwable t) {
            //end the current transaction without committing
            db.endTransaction();
            //begin a new transaction to let the app continue
            //this also increments the db version
            db.beginTransaction();
        }
    }

    public int getActualVersion() { return this._actual_version; }
}

在我的数据库适配器类中:

class DBAdapter {
    private final DBHelper dbHelper;
    SQLiteDatabase dbW;

    public DBAdapter(Context context) {
        dbHelper = new DBHelper(context);
        dbW = dbHelper.getWritableDatabase();

        if (dbHelper.getActualVersion() != 2) {
            dbW.beginTransaction();
            dbW.setVersion(dbHelper.getActualVersion());
            dbW.setTransactionSuccessful();
            dbW.endTransaction();
        }
    }
}

这是应用程序崩溃的堆栈跟踪。我通过在查询中使用CREATE TBLE而不是模拟错误。CREATE TABLE

2021-09-13 09:00:00 7931-7931/com.example.android.myapp E/SQLiteLog: (1) near "TBLE": syntax error in "CREATE TBLE setting (id INTEGER PRIMARY KEY, setting TEXT NOT NULL)"
2021-09-13 09:00:00 7931-7931/com.example.android.myapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.myapp, PID: 7931
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.myapp/com.example.android.myapp.MainActivity}: android.database.sqlite.SQLiteException: near "TBLE": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TBLE setting (id INTEGER PRIMARY KEY, setting TEXT NOT NULL)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: android.database.sqlite.SQLiteException: near "TBLE": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TBLE setting (id INTEGER PRIMARY KEY, setting TEXT NOT NULL)
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1045)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:652)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:61)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:33)
        at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1919)
        at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1841)
        at com.example.android.myapp.DBHelper.onUpgrade(DBHelper.java:159)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:416)
        at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:340)
        at com.example.android.myapp.DBAdapter.<init>(DBAdapter.java:49)
        at com.example.android.myapp.MainActivity.onCreate(MainActivity.java:59)
        at android.app.Activity.performCreate(Activity.java:7994)
        at android.app.Activity.performCreate(Activity.java:7978)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

标签: javaandroidsqlitesqliteopenhelperversionupgrade

解决方案


推荐阅读