2017-09-26 1 views
1

J'ai une application qui utilise la persistance de pièce en mode production. Il semble que lorsque je tente de mettre à jour une table, j'ai l'erreur suivante sur certains appareils: Ma connexion avec la base de données est ouverte à tout moment, seulement sur détruire je libère la base de données.Erreur de persistance de pièce

Ceci est mon service qui fonctionne toutes les 12 heures

C'est Service: https://gist.github.com/anonymous/8fac7650b34aa19229d5f6b91d2454d4 DataRepo: https://gist.github.com/anonymous/70c524c1e8eb5e7ed893131a9c685b5b AppDatabase https://gist.github.com/anonymous/ccb20853054fa5d453592fd2653a4dc4

l'erreur:

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

Vous ne devez en aucun cas fermer la base de données. Pouvez-vous partager le code pertinent? –

+0

Ce code est dans un service .. – Cliff

+0

@XavierRubioJansana vérifier mon édition – Cliff

Répondre

1

DatabaseRepository est enroulant un appel à Room.databaseBuilder(). Comme cela est implémenté à l'aide d'un singleton, vous fermez la base de données dans l'appel à databaseRepository.databaseClose();, mais sans ouvrir à nouveau. La création d'un nouveau DatabaseRepository dans votre code n'aide pas, car AppDatabase.getAppDatabase(ctx); retournera la même base de données fermée.

Ainsi, les solutions possibles sont les suivants:

  • Retirez l'appel à databaseRepository.databaseClose();, que le service est en cours d'exécution dans le même Application que le reste de vos activités, et la base de données est (et doit être) partagé. C'est la solution préférée à mon avis.
  • Une alternative sera que DatabaseRepository#databaseClose() détruit également l'objet de base de données en appelant AppDatabase.destroyInstance();. Pour moi, cela est peut poser d'autres questions, comme les problèmes de concurrence, a conservé les références à l'ancien objet de base de données (par exemple dans une activité), etc.

code pour la deuxième, pas recommandé solution:

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