Android:尽管代码已不存在,但过去的实现中的数据库仍被神秘地创建

时间:2019-03-06 02:30:37

标签: android android-room

我正在创建一个Android应用,并且在数据库的不同实现之间来回弹跳。无论出于何种原因,即使我似乎删除了过去实现中的所有代码,我的应用仍在我的数据文件夹中创建来自过去实现的数据库,而不是当前数据库。这是一些有关如何更改数据库实现的上下文。

  1. 我首先开始使用SQLiteOpenHelper创建数据库,但是当我发现Room Persistence Library时很快放弃了该实现。
  2. 我使用Room创建了一个数据库,其中包含三个实体:SubTaskMainTask,以及用于关联这两个实体的联结表/实体。
  3. 我意识到创建联结表并不是最佳实现,因为SubTask只能属于一个MainTask。因此,我报废了联结实体,并向SubTask添加了一个与MainTask相关的属性。这是我目前的实现方式,我打算坚持下去。

这是我数据库的当前代码。我决定填充它,看看它是否可以翻译:

@Database(entities = {SubTask.class, MainTask.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {

public static final String DATABASE_NAME = "task_db";

private static AppDatabase instance;

public static synchronized AppDatabase getInstance(final Context context) {
    if (instance == null) {
        instance = Room.databaseBuilder(
                context.getApplicationContext(),
                AppDatabase.class,
                DATABASE_NAME
        ).fallbackToDestructiveMigration().addCallback(roomCallback).build();
    }

    return instance;
}

public abstract SubTaskDao getSubTaskDao();

public abstract MainTaskDao getMainTaskDao();

//TESTING TO POPULATE DATABASE
private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
    @Override
    public void onCreate(@NonNull SupportSQLiteDatabase db) {
        super.onCreate(db);
        new PopulateDbAsyncTask(instance).execute();
    }
};

private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {
    private MainTaskDao mainTaskDao;
    private SubTaskDao subTaskDao;

    private PopulateDbAsyncTask(AppDatabase db) {
        mainTaskDao = db.getMainTaskDao();
        subTaskDao = db.getSubTaskDao();
    }

    @Override
    protected Void doInBackground(Void... voids) {
        Calendar date1 = Calendar.getInstance();
        date1.set(2019, 2, 10);
        mainTaskDao.insertMainTasks(new MainTask("School Assignments", 0xFF0000, date1));

        Calendar date2 = Calendar.getInstance();
        date2.set(2019, 2, 8);
        subTaskDao.insertSubTasks(new SubTask("Read database book", date2, 1));

        Calendar date3 = Calendar.getInstance();
        date3.set(2019, 2, 6);
        subTaskDao.insertSubTasks(new SubTask("Read OS book", date3, 1));

        return null;
    }
}
}

当我第一次构建并打开我的应用程序时,它崩溃了,并且我在日志中得到以下内容:

2019-03-05 19:53:36.241 20085-20106/com.myname.divideandconquer E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: com.myname.divideandconquer, PID: 20085
java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
    at android.arch.persistence.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:135)
    at android.arch.persistence.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:115)
    at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:151)
    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:409)
    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:298)
    at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)
    at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
    at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:233)
    at com.johnsorhannus.divideandconquer.room.SubTaskDao_Impl$4.compute(SubTaskDao_Impl.java:159)
    at com.johnsorhannus.divideandconquer.room.SubTaskDao_Impl$4.compute(SubTaskDao_Impl.java:145)
    at android.arch.lifecycle.ComputableLiveData$2.run(ComputableLiveData.java:100)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:764)

当我在设备文件资源管理器中查看时,我的应用程序会看到以下内容: Image 1task_db是使用Room创建的数据库。我使用第三方应用程序打开了该数据库,该文件包含3个实体(而不是2个)的表,因此这似乎来自实现(2)。 taskManager是我使用SQLiteOpenHelper创建的数据库(实现1),其中填充有我已硬编码到数据库中的数据。我对为什么这个数据库存在感到困惑。我已经从该实现中删除了所有代码。我什至在整个项目中搜索了taskManager,以查看是否在代码中的任何地方给数据库指定了这个名称。没事!

当我进入应用程序设置并清除存储,然后再次在Android Studio上运行该应用程序时,日志中没有错误,并且在我的设备文件资源管理器中得到了以下内容:Image 2task_db完全为空。根本没有表,所以我不确定这是来自实现(2)还是(3)。这也是令人惊讶的,因为我希望数据库中将填充我硬编码的值。

即使我从过去的两个实现中删除了代码,我也不知道为什么要创建这些数据库。这里不再包含来自SQLiteOpenHelper的任何代码痕迹,并且我删除了联结表的Dao和Entity。有什么线索吗?

2 个答案:

答案 0 :(得分:0)

查看错误。它向您显示了错误原因。

  

java.lang.IllegalStateException:Room无法验证数据完整性。看起来您已更改架构,但忘记更新版本号。您只需增加版本号即可解决此问题。

因此,您已在代码中更改了某些架构。因此,只需将数据库版本从1更改为2。

Database(entities = {SubTask.class, MainTask.class}, version = 2)

答案 1 :(得分:0)

您必须卸载应用程序(或从内部存储中删除文件),否则先前版本的Room模式将持久存在(就像使用{{ 1}}),然后将新架构与旧架构进行比较。打算创建迁移时,增加版本号仅对已经发布的应用有意义。