Diese Frage ist etwas alt, aber immer noch sehr relevant. Beachten Sie, dass Sie db.close () in Ihrer ContentProvider-Implementierung NICHT aufrufen müssen , wenn Sie die Dinge auf "moderne" Weise ausführen (z. B. LoaderManager verwenden und CursorLoaders erstellen, um einen ContentProvider in einem Hintergrundthread abzufragen) . Beim Versuch, auf den ContentProvider in einem Hintergrundthread zuzugreifen, kam es zu allen möglichen Abstürzen im Zusammenhang mit CursorLoader / AsyncTaskLoader, die durch Entfernen der Aufrufe von db.close () behoben wurden.
Wenn Sie also auf Abstürze stoßen, die so aussehen (Jelly Bean 4.1.1):
Caused by: java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:962)
at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:677)
at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348)
at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at android.content.ContentResolver.query(ContentResolver.java:388)
at android.content.ContentResolver.query(ContentResolver.java:313)
at com.hindsightlabs.paprika.loaders.GroceryListLoader.loadInBackground(GroceryListLoader.java:147)
at com.hindsightlabs.paprika.loaders.GroceryListLoader.loadInBackground(GroceryListLoader.java:1)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 4 more
Oder dies (ICS 4.0.4):
Caused by: java.lang.IllegalStateException: database /data/data/com.hindsightlabs.paprika/databases/Paprika.db (conn
at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2215)
at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:436)
at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:422)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:79)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:164)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:156)
at android.content.ContentResolver.query(ContentResolver.java:318)
at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:49)
at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:35)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 4 more
Oder wenn in LogCat Fehlermeldungen angezeigt werden, die folgendermaßen aussehen:
Cursor: invalid statement in fillWindow()
Überprüfen Sie anschließend Ihre ContentProvider-Implementierung und stellen Sie sicher, dass Sie die Datenbank nicht vorzeitig schließen. Nach dieser wird erhalten die Contentprovider automatisch gereinigt , wenn der Prozess ohnehin getötet wird, so dass Sie die Datenbank vor der Zeit nicht brauchen , zu schließen.
Stellen Sie jedoch sicher, dass Sie immer noch richtig sind:
- Schließen Sie Ihre Cursor, die von ContentProvider.query () zurückgegeben werden . (CursorLoader / LoaderManager erledigt dies automatisch für Sie. Wenn Sie jedoch direkte Abfragen außerhalb des LoaderManager-Frameworks ausführen oder eine benutzerdefinierte CursorLoader / AsyncTaskLoader-Unterklasse implementiert haben, müssen Sie sicherstellen, dass Sie Ihre Cursor bereinigen richtig.)
- Implementieren Sie Ihren ContentProvider threadsicher. (Der einfachste Weg, dies zu tun, besteht darin, sicherzustellen, dass Ihre Datenbankzugriffsmethoden in einen synchronisierten Block eingeschlossen sind.)