2017-07-28 68 views
5

當使用客房從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訪問數據庫的任何嘗試都發生此錯誤。

回答

19

這是因爲你試圖修改現有數據庫的架構而沒有提供任何遷移信息。所以基本上它試圖將新的數據庫模式寫入現有的不起作用的數據庫。

有兩種解決方法。如果你在你的開發環境,你可以做的是回退到破壞性遷移,要做到這一點你的數據庫創建的代碼看起來像下面這樣:

MyDatabase myDatabase = Room.databaseBuilder(context, MyDatabase.class, "my-db") 
    .fallbackToDestructiveMigration() 
    .build(); 

這意味着當您提供更新或數據庫新實體,它將執行@huw所說的答案,並刪除應用程序安裝中的數據庫,從中刪除所有數據併爲您提供全新安裝。

另一種方法是使用遷移功能。他們是長這麼漂亮,除非有人要我在這裏寫了,我會離開它現在,但基本上,文檔可以在這裏找到:

Room DB Migration Documentation

這本質上使DB運行提供了一些SQL自己將數據庫更新到新版本。通過這種方式,您可以確保在執行遷移時不會丟失任何數據;或儘可能少取決於你在做什麼。這是生產應用程序的首選方法,因爲這意味着用戶不會丟失預先存在的數據,並且不會收到很多憤怒的評論/丟失的客戶。

希望能夠幫助!

+2

請記住在@Database批註中更改數據庫版本。 fallbackToDestructiveMigration()不會因爲數據庫結構被更改而重置數據庫。 – Andrew

5

解決此問題的一個辦法是刪除數據庫文件並重新啓動。這不是一個問題,因爲我只是在測試並可以使用在線數據重新填充數據庫。

這樣做可以:

  • 應用信息>存儲>清除數據
  • 手動刪除文件在/data/data/com.app.example/databases/database.db
相關問題