2017-09-26 57 views
1

我有一个在生产模式下使用房间持久性的应用程序。它似乎当我尝试更新表,我有一些设备上有以下错误:我的数据库连接是打开的所有时间,只有在销毁我释放数据库。房间持久性错误

这是我的服务运行,每12小时

这是服务:https://gist.github.com/anonymous/8fac7650b34aa19229d5f6b91d2454d4 DataRepo: https://gist.github.com/anonymous/70c524c1e8eb5e7ed893131a9c685b5b AppDatabase https://gist.github.com/anonymous/ccb20853054fa5d453592fd2653a4dc4

错误:

java.lang.IllegalStateException: 
    at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked 
    (SQLiteDatabase.java:2199) 
    at android.database.sqlite.SQLiteDatabase.createSession 
    (SQLiteDatabase.java:379) 
    at android.database.sqlite.SQLiteDatabase$1.initialValue 
    (SQLiteDatabase.java:92) 
    at android.database.sqlite.SQLiteDatabase$1.initialValue 
    (SQLiteDatabase.java:89) 
    at java.lang.ThreadLocal$Values.getAfterMiss (ThreadLocal.java:430) 
    at java.lang.ThreadLocal.get (ThreadLocal.java:65) 
    at android.database.sqlite.SQLiteDatabase.getThreadSession 
    (SQLiteDatabase.java:373) 
    at android.database.sqlite.SQLiteProgram.getSession (SQLiteProgram.java:101) 
    at android.database.sqlite.SQLiteStatement.executeUpdateDelete 
    (SQLiteStatement.java:64) 
    at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete (FrameworkSQLiteStatement.java:75) 
    at android.arch.persistence.room.EntityDeletionOrUpdateAdapter.handle (EntityDeletionOrUpdateAdapter.java:69) 
     at mbc.analytics.sdk.room.dao.TimeDao_Impl.updateTimeModel (TimeDao_Impl.java:122) 
     at mbc.analytics.sdk.room.database.DatabaseRepository.createTimeEntity (DatabaseRepository.java:211) 
     at mbc.analytics.sdk.room.database.DatabaseRepository.createAppEntity (DatabaseRepository.java:56) 
     at mbc.analytics.sdk.services.LollipopService.getStats (LollipopService.java:202) 
     at mbc.analytics.sdk.services.LollipopService.access$900 (LollipopService.java:39) 
    at mbc.analytics.sdk.services.LollipopService$2.run (LollipopService.java:153) 
     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) 
+0

您不应以任何方式关闭数据库。你能分享相关的代码吗? –

+0

此代码是在一个服务.. – Cliff

+0

@XavierRubioJansana检查我的编辑 – Cliff

回答

1

DatabaseRepository披着通话到Room.databaseBuilder()。由于这是使用单例实现的,因此您在调用databaseRepository.databaseClose();时关闭数据库,但不能再次打开。在代码中创建新的DatabaseRepository不会有帮助,因为AppDatabase.getAppDatabase(ctx);将返回相同的封闭数据库。

所以,可能的解决方案是:

  • 删除调用databaseRepository.databaseClose();,因为服务是一样Application作为活动的其余部分内运行,并且数据库(也应该)共享。 在我看来,这是首选解决方案
  • 另一种方法是DatabaseRepository#databaseClose()也会通过调用AppDatabase.destroyInstance();销毁数据库对象。对我来说,这是可能会造成其他问题,如并发问题,保留旧的数据库对象(例如,在一个活动),第二参考等

代码,不建议解决方案:

public void databaseClose() { 
    if (db.isOpen()) { 
     db.close(); 
     AppDatabase.destroyInstance(); 
    } 
}