Android + Room +尝试重新打开已关闭的对象:SQLiteDatabase:-添加迁移后

时间:2018-11-21 04:55:32

标签: android android-room android-architecture-components

我已经为我的一个android应用程序添加了Romm数据库库,并且现在已经有一段时间可以正确使用它了,但是现在我必须更新该应用程序,并且要向其中添加数据库迁移。

为此,我关注了多个教程,博客和官方文档,并尝试添加迁移。

但是,当我尝试添加数据库迁移时,即使添加了多个版本(例如, java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: (database path)

这是迁移的代码。

val MIGRATION_4_5: Migration = object : Migration(4, 5) {
        override fun migrate(database: SupportSQLiteDatabase) {
//                database.execSQL("ALTER TABLE timetracker ADD COLUMN tempId TEXT")

            // 1. Create new table
            database.execSQL("CREATE TABLE timetrackerTemp ( 
            contentId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
            time INTEGER, tempId TEXT );")

            // 2. Copy the data
            database.execSQL("INSERT INTO timetrackerTemp ( 
            contentId, time, tempId ) SELECT contentId, time, 
            tempId FROM timetracker")

            // 3. Remove the old table
            database.execSQL("DROP TABLE timetracker")

            // 4. Change the table name to the correct one
            database.execSQL("ALTER TABLE timetrackerTemp RENAME TO timetracker")
        }
    }

这是获取数据库对象的代码,

daoInstance = Room.databaseBuilder(this, AppDatabase::class.java, "myapp.db")
            .allowMainThreadQueries()
            .addMigrations(AppDatabase.MIGRATION_4_5)
            .build()

如果有人有任何想法,请帮助。

崩溃日志,

  

E / Android运行时:致命异常:主要       java.lang.RuntimeException:无法暂停活动{com.example.dev/com.example.content.appview.content.ContentActivity}:java.lang.IllegalStateException:尝试重新打开已经关闭的对象:SQLiteDatabase:/数据/用户/0/com.example.dev/数据库/test.db           在android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:3746)           在android.app.ActivityThread.performPauseActivity(ActivityThread.java:3712)           在android.app.ActivityThread.performPauseActivity(ActivityThread.java:3686)           在android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3660)           在android.app.ActivityThread.-wrap16(ActivityThread.java)           在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1485)           在android.os.Handler.dispatchMessage(Handler.java:102)           在android.os.Looper.loop(Looper.java:154)           在android.app.ActivityThread.main(ActivityThread.java:6123)           在java.lang.reflect.Method.invoke(本机方法)           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:867)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)        引起原因:java.lang.IllegalStateException:尝试重新打开一个已经关闭的对象:SQLiteDatabase:/data/user/0/com.example.dev/databases/test.db           在android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)           在android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1660)           在android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1606)           在android.arch.persistence.db.framework.FrameworkSQLiteDatabase.execSQL(FrameworkSQLiteDatabase.java:242)           位于com.example.base.database.AppDatabase $ Companion $ MIGRATION_4_5 $ 1.migrate(AppDatabase.kt:40)           在android.arch.persistence.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:85)           在android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper $ OpenHelper.onUpgrade(FrameworkSQLiteOpenHelper.java:133)           在android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:256)           在android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)           在android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper $ OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)           在android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)           在android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:233)           在com.example.base.database.daos.TimeTrackerContentDao_Impl.getAll(TimeTrackerContentDao_Impl.java:134)           在com.example.content.appview.content.ContentActivity.onPause(ContentActivity.kt:600)           在android.app.Activity.performPause(Activity.java:6812)           在android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1344)           在android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:3735)           在android.app.ActivityThread.performPauseActivity(ActivityThread.java:3712)           在android.app.ActivityThread.performPauseActivity(ActivityThread.java:3686)           在android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3660)           在android.app.ActivityThread.-wrap16(ActivityThread.java)           在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1485)           在android.os.Handler.dispatchMessage(Handler.java:102)           在android.os.Looper.loop(Looper.java:154)           在android.app.ActivityThread.main(ActivityThread.java:6123)           在java.lang.reflect.Method.invoke(本机方法)           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:867)           com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

谢谢。

2 个答案:

答案 0 :(得分:0)

您必须尝试2种解决方案:

  • 表名列名应写为`table_name`,`column_name`

  • 使用运算符 NOT NULL 时应写 DEFAULT值

    例如 ALTER TABLE `card` ADD COLUMN `status` INTEGER DEFAULT 0 NOT NULL

答案 1 :(得分:-1)

请确保数据库架构也已更改为5

@[Database(
        entities = [
             /* ... */
        ],
        version = 5
)