房间持久性库:尝试重新打开已经关闭的对象

时间:2017-08-23 00:33:39

标签: android sqlite android-room

当我使用1.0.0-alpha5版本的Room Persistence Library时,一切正常。但是,在更新到1.0.0-alpha9版本后,我收到此错误:

  

java.lang.IllegalStateException:尝试重新打开已经关闭的   object:SQLiteDatabase:/ data / data / package_name / databases / app_db

我该如何解决这个问题?

修改

我正在使用带有匕首2的MVP架构。我有DatabaseHelper类初始化RoomDatabase:

@Singleton
public class DatabaseHelper {

private final AppDatabase appDatabase;

@Inject
public DatabaseHelper(@ApplicationContext Context context) {
    appDatabase = Room.databaseBuilder(context, AppDatabase.class, "app_db").build();        
}

public List<DifficultyEntity> getAllDifficulties() {
        return appDatabase.difficultyDao().getAllDifficulties();
}

我的会议室数据库:

@Database(version = 22, entities = {
        DifficultyEntity.class, // ....
})
@Singleton
public abstract class AppDatabase extends RoomDatabase {

    public abstract DifficultyDao difficultyDao();
    //....
}

当我调用getAllDifficulties方法时,我收到了该错误。

这里是logcat:

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/package_name/databases/app_db
       at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
       at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1783)
       at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1729)
       at android.arch.persistence.db.framework.FrameworkSQLiteDatabase.execSQL(FrameworkSQLiteDatabase.java:241)
       at android.arch.persistence.room.RoomOpenHelper.createMasterTableIfNotExists(RoomOpenHelper.java:130)
       at android.arch.persistence.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:106)
       at android.arch.persistence.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:99)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$1.onOpen(FrameworkSQLiteOpenHelper.java:64)
       at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:266)
       at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:106)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:82)
       at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:191)
       at uz.iumarov.ieltsspeaking.data.local.database.daos.RecordingDao_Impl.getAllRecordings(RecordingDao_Impl.java:167)
       at uz.iumarov.ieltsspeaking.data.local.database.DatabaseHelper.getAllRecording(DatabaseHelper.java:361)
       at uz.iumarov.ieltsspeaking.ui.main.recordingsFragment.RecordingsPresenter$1.call(RecordingsPresenter.java:77)
       at uz.iumarov.ieltsspeaking.ui.main.recordingsFragment.RecordingsPresenter$1.call(RecordingsPresenter.java:74)
       at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)
       at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
       at rx.Observable.unsafeSubscribe(Observable.java:10151)
       at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
       at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
       at rx.Observable.unsafeSubscribe(Observable.java:10151)
       at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
       at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$1.call(EventLoopsScheduler.java:172)
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)

编辑2:

过了一段时间,我开始得到不同的错误:

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:118)
       at android.arch.persistence.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:99)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$1.onOpen(FrameworkSQLiteOpenHelper.java:64)
       at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:266)
       at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:106)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:82)
       at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:191)
       at uz.iumarov.ieltsspeaking.data.local.database.daos.RecordingDao_Impl.getAllRecordings(RecordingDao_Impl.java:167)
       at uz.iumarov.ieltsspeaking.data.local.database.DatabaseHelper.getAllRecording(DatabaseHelper.java:361)
       at uz.iumarov.ieltsspeaking.ui.main.recordingsFragment.RecordingsPresenter$1.call(RecordingsPresenter.java:77)
       at uz.iumarov.ieltsspeaking.ui.main.recordingsFragment.RecordingsPresenter$1.call(RecordingsPresenter.java:74)
       at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)
       at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
       at rx.Observable.unsafeSubscribe(Observable.java:10151)
       at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
       at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
       at rx.Observable.unsafeSubscribe(Observable.java:10151)
       at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
       at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$1.call(EventLoopsScheduler.java:172)
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)

当我更新版本号时,我收到了迁移错误:

java.lang.IllegalStateException: A migration from 22 to 23 is necessary. Please provide a Migration in the builder or call fallbackToDestructiveMigration in the builder in which case Room will re-create all of the tables.
       at android.arch.persistence.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:81)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$1.onUpgrade(FrameworkSQLiteOpenHelper.java:49)
       at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:256)
       at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:106)
       at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:82)
       at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:191)
       at uz.iumarov.ieltsspeaking.data.local.database.daos.RecordingDao_Impl.getAllRecordings(RecordingDao_Impl.java:167)
       at uz.iumarov.ieltsspeaking.data.local.database.DatabaseHelper.getAllRecording(DatabaseHelper.java:361)
       at uz.iumarov.ieltsspeaking.ui.main.recordingsFragment.RecordingsPresenter$1.call(RecordingsPresenter.java:77)
       at uz.iumarov.ieltsspeaking.ui.main.recordingsFragment.RecordingsPresenter$1.call(RecordingsPresenter.java:74)
       at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)
       at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
       at rx.Observable.unsafeSubscribe(Observable.java:10151)
       at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
       at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
       at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
       at rx.Observable.unsafeSubscribe(Observable.java:10151)
       at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
       at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$1.call(EventLoopsScheduler.java:172)
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)

拜托,有人帮助我!

解决

我删除了我的应用并重新安装了。现在,alpha9 verison一切正常。

2 个答案:

答案 0 :(得分:8)

您必须提供Migration.In Live App,您无法告诉每个人请删除应用并重新安装应用。

In Room新版本1.0.0-alpha9 Room增加了对NOT NULL约束的支持。

这将改变Room生成的架构。因为它会更改架构,所以它还会更改数据库的identityHash以及Room用于唯一标识每个数据库版本的身份。因此,我们需要迁移

对于从1.0.0-alpha5迁移到1.0.0-alpha9,请访问以下文章。非常好的文章,从旧版本迁移到1.0.0-alpha9版本。

https://medium.com/@manuelvicnt/android-room-upgrading-alpha-versions-needs-a-migration-with-kotlin-or-nonnull-7a2d140f05b9

答案 1 :(得分:0)

有同样的问题。 请注意,数据库在卸载后可能会持续存在。

您需要做的清单

    android:allowBackup="false"