间试图重新打开已经关闭的数据库
问题描述:
当使用客房从Android体系结构组件,我收到试图用匕首组件来访问数据库时出现以下错误:间试图重新打开已经关闭的数据库
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: (database path)
我用匕首版本2.11
和房间版本1.0.0-alpha7
。该错误在版本1.0.0-alpha5
上可重现。
在初始化数据库并将其注入到我的类中后,通过DAO访问数据库的任何尝试都发生此错误。
答
这是因为你试图修改现有数据库的架构而没有提供任何迁移信息。所以基本上它试图将新的数据库模式写入现有的不起作用的数据库。
有两种解决方法。如果你在你的开发环境,你可以做的是回退到破坏性迁移,要做到这一点你的数据库创建的代码看起来像下面这样:
MyDatabase myDatabase = Room.databaseBuilder(context, MyDatabase.class, "my-db")
.fallbackToDestructiveMigration()
.build();
这意味着当您提供更新或数据库新实体,它将执行@huw所说的答案,并删除应用程序安装中的数据库,从中删除所有数据并为您提供全新安装。
另一种方法是使用迁移功能。他们是长这么漂亮,除非有人要我在这里写了,我会离开它现在,但基本上,文档可以在这里找到:
Room DB Migration Documentation
这本质上使DB运行提供了一些SQL自己将数据库更新到新版本。通过这种方式,您可以确保在执行迁移时不会丢失任何数据;或尽可能少取决于你在做什么。这是生产应用程序的首选方法,因为这意味着用户不会丢失预先存在的数据,并且不会收到很多愤怒的评论/丢失的客户。
希望能够帮助!
答
解决此问题的一个办法是删除数据库文件并重新启动。这不是一个问题,因为我只是在测试并可以使用在线数据重新填充数据库。
这样做可以:
- 应用信息>存储>清除数据
- 手动删除文件在
/data/data/com.app.example/databases/database.db
请记住在@Database批注中更改数据库版本。 fallbackToDestructiveMigration()不会因为数据库结构被更改而重置数据库。 – Andrew