Android: база данных прошлых реализаций создавалась таинственным образом, несмотря на то, что код больше не существует - PullRequest
0 голосов
/ 06 марта 2019

Я нахожусь в процессе создания приложения для Android, и я перебегал назад и вперед между различными реализациями моей базы данных. И по какой-то причине мое приложение создает базы данных из моей прошлой реализации, а не из текущей, в моей папке данных, хотя я, казалось бы, удалил весь код из моих прошлых реализаций. Вот некоторый контекст о том, как я изменил мою реализацию базы данных.

  1. Я впервые начал создавать свою базу данных, используя SQLiteOpenHelper, но быстро отказался от этой реализации, когда обнаружил Библиотеку постоянства в комнате.
  2. Я создал базу данных, используя Room для 3 сущностей: SubTask, MainTask и соединительную таблицу / сущность для связи этих двух сущностей.
  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)

Когда я смотрю в Device File Explorer, я вижу следующее для моего приложения: Изображение 1 . task_db - база данных, созданная с помощью Room. Я открыл эту базу данных с помощью стороннего приложения, и этот файл содержит таблицы для 3 сущностей, а не 2, так что, похоже, это из реализации (2). taskManager - это база данных, которую я создал с использованием SQLiteOpenHelper (реализация 1), и она заполнена данными, которые я жестко закодировал в базу данных. Я озадачен тем, почему эта база данных существует. Я удалил весь свой код из этой реализации. Я даже искал во всем моем проекте taskManager, чтобы узнать, дал ли я когда-нибудь базе данных это имя где-нибудь в моем коде. Ничего!

Когда я захожу в настройки приложения и очищаю хранилище и снова запускаю приложение в Android Studio, я не получаю ошибку в журнале и получаю в обозревателе файлов устройств следующее: Изображение 2 . task_db полностью пусто. Нет таблиц вообще, поэтому я не совсем уверен, что это из реализации (2) или (3). Это также удивительно, потому что я ожидал, что база данных будет заполнена значениями, которые я жестко закодировал.

Я понятия не имею, почему создаются эти базы данных, хотя я удалил код из моих последних двух реализаций. Там больше нет следов кода из SQLiteOpenHelper, и я удалил Dao и Entity для таблицы соединений. Любой ключ к пониманию того, что происходит?

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

Вы должны удалить приложение (или удалить файлы из внутреннего хранилища), иначе схема Room предыдущей версии сохранится (точно так же, как и при сохранении этих файлов при создании SQLiteOpenHelper)и тогда новая схема будет сравниваться со старой схемой.увеличение номера версии имеет смысл только для уже выпущенных приложений, когда планируется создать миграцию.

0 голосов
/ 06 марта 2019

Посмотрите на ошибку.он показывает вам причину ошибки.

java.lang.IllegalStateException: Комната не может проверить целостность данных.Похоже, вы изменили схему, но забыли обновить номер версии.Вы можете просто исправить это, увеличив номер версии.

Итак, вы изменили некоторую схему в своем коде.Поэтому просто измените версию базы данных с 1 на 2.

Database(entities = {SubTask.class, MainTask.class}, version = 2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...