DB onUpgrade SQLiteException от BroadcastReceiver - PullRequest
0 голосов
/ 01 ноября 2018

Я реализовал логику для обновления моей базы данных до новых версий. И все работает нормально, иначе я бы получил тысячи аварий. В любом случае во время 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 (); call загружает все данные из базы данных, используя метод 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?

1 Ответ

0 голосов
/ 01 ноября 2018

Вы пытались переместить логику в IntentService? Вещательные приемники не должны обрабатывать длинные операции, они должны работать только как диспетчер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...