我已经实现了将数据库升级到新版本的逻辑。而且一切正常,否则我会崩溃成千上万。
无论如何,每月在onUpgrade期间发生约100次崩溃,而所有这些崩溃均来自BroadcastReceiver BOOT_COMPLETED
。
这是崩溃日志:
android.database.sqlite.SQLiteException:
at android.database.sqlite.SQLiteConnection.nativePrepareStatement (SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement (SQLiteConnection.java:903)
at android.database.sqlite.SQLiteConnection.prepare (SQLiteConnection.java:514)
at android.database.sqlite.SQLiteSession.prepare (SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init> (SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init> (SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql (SQLiteDatabase.java:1770)
at android.database.sqlite.SQLiteDatabase.execSQL (SQLiteDatabase.java:1698)
at com.abdula.pranabreath.common.helpers.DbUpgradeHelper.upgradeToTrngSounds (DbUpgradeHelper.java:213)
at com.abdula.pranabreath.common.helpers.DbOpenHelper.onUpgrade (DbOpenHelper.java:101)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:398)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:298)
at com.abdula.pranabreath.common.helpers.DbOpenHelper.getAllMeta (DbOpenHelper.java:224)
at com.abdula.pranabreath.model.proxies.ControlProxy.queryMetadata (ControlProxy.java:101)
at com.abdula.pranabreath.presenter.Presenter.bindData (Presenter.java:179)
at com.abdula.pranabreath.presenter.receivers.ReminderBootCompletedReceiver$1.run (ReminderBootCompletedReceiver.java:27)
因此,此BOOT_COMPLETED
接收器从数据库加载所有提醒,并计划下一个警报触发时间。
这是接收器类:
public void onReceive(final Context context, Intent intent) {
final String action = intent.getAction();
final PendingResult result = goAsync();
final Thread thread = new Thread() {
public void run() {
switch (action) {
case Intent.ACTION_BOOT_COMPLETED:
sPresenter.bindData();
ReminderDelegate.setNextReminder();
break;
}
result.finish();
}
};
thread.start();
}
}
sPresenter.bindData();调用使用getAllMeta方法从数据库加载所有数据,然后从内部调用getWritableDatabase()。调用onUpgrade之后。 在这种情况下,似乎用户已经升级了该应用程序,但尚未打开它,而是重新启动了设备。 onUpgrade方法:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
int version = oldVersion;
db.beginTransaction();
switch (version) {
case LAUNCH_VERSION:
DbUpgradeHelper.upgradeToAccurateExp(db);
version = ACCURATE_EXP_VERSION;
case ACCURATE_EXP_VERSION:
DbUpgradeHelper.upgradeToGuruRelease(db);
version = GURU_RELEASE_VERSION;
case GURU_RELEASE_VERSION:
DbUpgradeHelper.upgradeToMeditation(db);
version = MEDITATION_VERSION;
case MEDITATION_VERSION:
DbUpgradeHelper.upgradeToTrngSounds(db);
version = TRNG_SOUNDS_VERSION;
}
db.setTransactionSuccessful();
db.endTransaction();
}
以及实际上发生崩溃的最后一种方法:
static void upgradeToTrngSounds(final SQLiteDatabase db) {
db.execSQL("ALTER TABLE trainings ADD COLUMN public_id INTEGER"); // CRASH HERE
db.execSQL("UPDATE trainings SET public_id = user_owner");
db.execSQL("ALTER TABLE trainings ADD COLUMN dur_mode INTEGER DEFAULT 0");
}
没有其他抱怨-仅SQLiteException。 如果onUpgrade无法在UI线程上执行是否有问题,能否请您帮助我找出答案?还是BroadcastReceiver有问题?
答案 0 :(得分:0)
您是否尝试过将逻辑移至IntentService?广播接收器不应处理长时间的操作,而应仅作为调度程序使用。