如果在我的扩展 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)