为什么在某些设备上会忽略SharedPreferences?

时间:2019-08-13 08:34:18

标签: java android sharedpreferences android-room

我使用Room进行了两步数据库迁移。迁移必须分两部分进行(v.2-> 3-> 4),因为必须在版本3和版本4之间使用新添加的表进行复杂的数据库操作。
我有一个SharedPreferences键值对,用于在用户迁移时保存信息。这是为了确保应用程序在迁移到版本4后不会尝试从2迁移到3。
从2到3的迁移只能在用户将应用程序从旧版本更新到新版本时运行。
这在我们的每个测试设备中都有效,但是Google Play的数据为我们提供了许多IllegalStateException崩溃报告,表明数据库试图降级。如果SharedPreferences检查正常工作,则不应发生这种情况。 以供参考。以下是一些迁移代码:

            if(!hasMigrated){
        if(NeedMigration.needMigrate(MyApplication.getAppContext())){
            ..
            try{
                //instantiate migration 2 to 3
                pdb=PreDatabase.getInstance(this);
                dRepo = new DayRepo(pdb, this, dayInstance);
                //db operations
                createDays();
                //store into SharedPrefs that we already migrated from 3
                NeedMigration.setHasMigrated(MyApplication.getAppContext());
            }catch(IllegalStateException e){
                Log.e("Database", "Already at version 4");
                ..
                return;
            }
            ..
            //instantiate migration from 3 to 4 (mig is in db.build)
            mdb = MyDatabase.getInstance(this);
            mRepo = Repository.fromContext(this);
            ..
        } else {
            /*
            If the user already has updated and the database exists in its newest state, skip straight to MyDatabase.java
            instantiation and load Day objects from database.
             */
            instantiateDatabase();
        }
        ..
        hasMigrated=true;
    }

hasMigrated布尔值只是一个静态布尔值,因此应用程序在运行时不会尝试再次实例化数据库。如果NeedMigration.needMigrate返回false,则仅实例化当前版本的数据库。 这是NeedMigrate类:

        private static final String MIG_PREFS= "migration_preferences";
private static final String MIG_HAS_UPDATED ="has_updated_to_four";

//if yes (true) then yes need migrate
//if false then no! no migrate
public static boolean needMigrate(Context activity){
    //compare versioncode with sharedprefs
    final SharedPreferences preferences = activity.getSharedPreferences(MIG_PREFS, Activity.MODE_PRIVATE);
    final boolean needmig =  preferences.getBoolean(MIG_HAS_UPDATED, true);
    return needmig;
}

public static void setHasMigrated(Context activity){
    final SharedPreferences prefs = activity.getSharedPreferences(MIG_PREFS, Activity.MODE_PRIVATE);
    //check if value exists
    SharedPreferences.Editor edit = prefs.edit();
    //false because if needMigrate is false then we dont need migrate
    edit.putBoolean(MIG_HAS_UPDATED, false);
    edit.commit();
}

再次让我澄清一下,这在我的测试设备上可以很好地工作,但是我们从Google收到了很多崩溃报告,这表明数据库试图在以前的版本上运行:

  

java.lang.IllegalStateException:           在androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:101)             在androidx.room.RoomOpenHelper.onDowngrade(RoomOpenHelper.java:113)             在androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper $ OpenHelper.onDowngrade上   (FrameworkSQLiteOpenHelper.java:144)在   android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked   (SQLiteOpenHelper.java:257)在   android.database.sqlite.SQLiteOpenHelper.getWritableDatabase   (SQLiteOpenHelper.java:2)在   androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper $ OpenHelper.getWritableSupportDatabase   (FrameworkSQLiteOpenHelper.java:96)在   androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase   (FrameworkSQLiteOpenHelper.java:54)在   androidx.room.RoomDatabase.query(RoomDatabase.java:256)在   androidx.room.util.DBUtil.query(DBUtil.java:54)位于   fi ...... controllers.database_controller.MealGroupDao _ .. PreDatabase_Impl.getMealGroupsInDay   (MealGroupDao _ .. PreDatabase_Impl.java:157)在   fi ..... DayRepo.lambda $ populateDayCache $ 0(DayRepo.java:301)在   fi ..... controllers.database_controller.repos .- $$ Lambda $ DayRepo $ gQGLM0kHLZLeLseqjFzeMTTO2fw.run   (-.java:8)在java.util.concurrent.ThreadPoolExecutor.runWorker   (ThreadPoolExecutor.java:1167)在   java.util.concurrent.ThreadPoolExecutor $ Worker.run   (ThreadPoolExecutor.java:641)在java.lang.Thread.run   (Thread.java:764)

我们刚刚收到一条评论,内容为“无法打开应用”,我怀疑这是原因。

为什么此SharedPreference检查被忽略,或者它只是返回错误的值?这是与上下文相关的问题,还是与NeedMigration类是静态的事实有关? 我尝试过:

  • 将上下文从活动更改为应用程序上下文
  • 将setHasMigrated调用移动到数据库2到3更新(DID NOT WORK ...)之前
  • 在很多地方添加try / catch块

0 个答案:

没有答案