SQLite SQLiteOpenHelper IllegalStateException – Error de DB ya cerrado

Esto me ha vuelto loco desde hace unos días. Tengo una aplicación de Android que es bastante complejo. Utiliza varios subprocesos para extraer datos de un servidor y rellenar la base de datos SQLite. Estoy usando un singleton para hacer referencia a mi extensión de SQLiteOpenHelper. Estoy abriendo y cerrando la base de datos en cada una de mis actividades.

El error sólo ocurre en una situación en la que estoy 4 actividades de profundidad y luego tratar de retroceder. He intentado varias formas de abrir y cerrar la base de datos, incluyendo mover el cierre de los métodos onDestroy () a onPause () y también agregar otro abierto a onResume ().

También de la nota, mis actividades hacen el uso pesado de ListViews y de ExpandableListViews, que entiendo podría causar la base de datos para cerrar sobre la base de este artículo: http://darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed- Automáticamente.html

He revisado el código y me aseguro de cerrar cualquiera de mis cursores o, si están siendo asignados a un adaptador, llamar a startManagingCursor ().

¿Alguien tiene una idea de lo que está pasando?

java.lang.RuntimeException: Unable to resume activity {com.fieldone/com.fieldone.DispatchActivity}: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3347) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3362) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2162) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:144) at android.app.ActivityThread.main(ActivityThread.java:4937) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:237) at android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:145) at android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:567) at android.app.Activity.performRestart(Activity.java:3836) at android.app.Activity.performResume(Activity.java:3857) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3337) ... 10 more 

ACTUALIZACIÓN: He arreglado el problema, pero no estoy seguro de por qué esto lo arregló. Por lo tanto, tal vez alguien por ahí sabe o podría explicar.

Cuando estoy en la cuarta actividad de la pila de actividades, estaba tratando de cerrar el db a través de db.close (). No importa dónde he puesto esto, en el onCreate después de obtener los datos que necesito, o en el onStop o onDestroy, se producirá este error. Si NO cierro el db, no voy a tener el problema. Por lo tanto, algo está causando el db para cerrar automáticamente. Lo extraño es que, aunque estoy utilizando un expandibleListView en esta actividad final, NO estoy usando un cursorAdapter. Alguien tiene alguna idea? Me encantaría entender esto.

Dado que esta pregunta ha recibido mucha atención, quería responder y describir lo que he aprendido y lo que funcionó para mí para corregir este problema en mi gran aplicación basada en bases de datos:

  1. NO utilice cursores administrados. Hay una razón por la que están obsoletos. Son completamente problemáticos. Realista, hay muy pocos escenarios en los que realmente necesita utilizar un cursor administrado de todos modos. En su lugar, ejecute su consulta y rellenar un objeto con los resultados. Si está consultando varias filas, cree una ArrayList <> de su objeto para mantener todas las filas. Lo que hago ahora es crear una función que ejecute la consulta y me devuelve mi ArrayList <> en lugar de un cursor en la devolución. Cierro el cursor dentro de la función y he terminado. Para un ListViews, ya no podrá utilizar un SimpleCursorAdapter. Basta con convertir todos estos a un BaseAdapter y utilizar su ArrayList <> objeto para llenarlo.

  2. NO OLVIDE CERRAR TODOS SUS CURSORES. Esto también puede causar estragos en las conexiones db de su aplicación. Pensé que estaba haciendo esto, pero, claro, encontré un lugar que no estaba cerrando explícitamente un cursor. Por lo tanto, ir a través de su aplicación y comprobar todos ellos.

También utilizo un objeto singleton DatabaseHelper. Declaro un objeto estático de DatabaseHelper dentro de mi clase de SQLiteOpenHelper de modo que consiga la misma instancia cada vez.

Ahora tengo una aplicación en ejecución estable que ya no recibe estos errores de DB. Espero que esta información sea útil para algunos de ustedes.

Utilice CursorAdapter.changeCursor (null), puede retardar la aparición de este error, pero no puede resolver completamente el problom, periodo de tiempo desconocido aparecerá de nuevo. ¡Esto también me ha vuelto loco!

También tuve el mismo problema 'db ya cerrado excepción con un cursor inválido en la declaración fillWindow () y IllegalStatementException'. Lo que hice fue poner mi cursor (w / c también viene de SimpleCursorAdapter) a una variable de instancia en lugar de una variable de método, a continuación, en mi onStop y onPause métodos llamo stopManagingCursor, a continuación, en mi onResume y métodos onStart que llamo startManagingCursor.

Resolvió mi problema para mí y no encontré ningún mensaje de error o de advertencia en mi logcat después de eso 🙂 Espero que esto ayude a cualquiera también.

  • SQLite en Android Cómo actualizar una fila específica
  • ¿JSON en un campo del sqlite?
  • Android Seleccionar fila por Id en Sqlite?
  • Insertar y seleccionar datos en árabe Android SQLite
  • Sugar ORM No hay tal tabla de excepción
  • Uso de SQLite desde libGDX en Android
  • Android: ¿necesito cerrar los objetos Cursor?
  • Cómo contar el número de registros en sqlite en Android
  • Limitar los registros obtenidos en Android (base de datos Sqlite)
  • Db-shm y db-wal en bases de datos sqlite
  • SQLite de Android "ENTRE" no incluye o devuelve todos los registros
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.