Я собираюсь ответить на свой вопрос, это описание проблемы.
Итак, у меня есть приложение, которое опубликовано в Магазине, и с новой версией, которую я хотелВ этом выпуске схема БД изменилась, поэтому мне, естественно, пришлось провести миграцию, которая позаботилась об обновлении ее с версии 3 до самой последней версии 5. Это включает в себя обеспечение миграции с 3 до 4 и с 4 до 5. Или с 3 до5 за один раз.
Так вот, что я и сделал, я предоставил эти миграции и отправил их в Room databaseBuilder (), и все было готово для имитации сценария, в котором происходит обновление приложения (установите Storeверсия, запустите ее, войдите в систему, создайте БД, создайте производственный APK и установите его на устройстве через терминал, запустите)
При этом всегда возникало следующее исключение:
05-19 02:38:00.363 6472-6522/co.myapp.app E/ROOM: Invalidation tracker is initialized twice :/.
05-19 02:38:00.378 6472-6549/co.myapp.app E/ROOM: Cannot run invalidation tracker. Is the db closed?
java.lang.IllegalStateException: The database '/data/user/0/co.myapp.app/databases/my_db' is not open.
at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2765)
at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:490)
at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:88)
at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:87)
at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:160)
at java.lang.ThreadLocal.get(ThreadLocal.java:150)
at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:484)
at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:107)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45)
at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)
Миграцииработали успешно, и таблицы создавались, как я написал, но это исключение продолжало появляться при каждом доступе к БДs операция сразу после того, как Room обновит вашу версию БД и выполнит миграцию.Каждое чтение или запись после обновления будет вызывать это исключение
- Сначала я подумал, что это проблема с миграциями, но миграции были правильными (SQL был проверен, а Room - нет).жаловаться на что-либо в этом роде, обычно это очень хорошо и говорит вам, что не соответствует).
- Тогда я подумал, что проблема заключалась в том, чтобы кормить его 2 миграциями одновременно (что я делал раньше,и не было никаких проблем), но я удалил миграцию 4-5 и поместил ее в 3-5, чтобы запустить все это за один раз.Бесполезно.
- Тогда я подумал, что я всегда могу сдаться и сказать «хорошо», просто сделайте fallbackToDestructiveMigration () и дайте Room восстановить все, в результате чего все пользователи выйдут из системы и получат своипотеря данных, что-то, чего я не хотел делать, но я просто хотел посмотреть, к чему это приведет.Поэтому я не кормил миграции и просто игнорировал их.Исключение все еще происходило.
Это исключение происходило тихо, оно не приводило к сбою приложения и не ссылалось ни на что в моем коде, оно просто происходило в Logcat и предотвращало любой вид доступа к БДмомент, когда это произошло хотя бы один раз.Независимо от того, вводили вы код миграции или нет, или хотите вернуться к деструктивной миграции или нет, в тот момент, когда Room обнаружит, что вы обновили вашу БД, она заблокирует ее и просто заблокирует любой доступ к ней.
Я проверял это на Samsung S6, Nexus 5, OnePlus, Motorola Moto C и Google Pixel, везде одинаковая проблема.