间试图重新打开已经关闭的数据库

问题描述:

当使用客房从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自己将数据库更新到新版本。通过这种方式,您可以确保在执行迁移时不会丢失任何数据;或尽可能少取决于你在做什么。这是生产应用程序的首选方法,因为这意味着用户不会丢失预先存在的数据,并且不会收到很多愤怒的评论/丢失的客户。

希望能够帮助!

+2

请记住在@Database批注中更改数据库版本。 fallbackToDestructiveMigration()不会因为数据库结构被更改而重置数据库。 – Andrew

解决此问题的一个办法是删除数据库文件并重新启动。这不是一个问题,因为我只是在测试并可以使用在线数据重新填充数据库。

这样做可以:

  • 应用信息>存储>清除数据
  • 手动删除文件在/data/data/com.app.example/databases/database.db