versiones pie oreo developer caracteristicas android

android - pie - Excepción: intento de adquirir una referencia en un SQLiteClosable cercano



android versiones (4)

Este me volvió loco por mucho tiempo. La solución que he encontrado es bastante simple: no guardo referencias a los objetos SQLiteDatabase . En su lugar, use un SQLiteOpenHelper y llame a getWritableDatabase() cada vez que lo necesite. De los documentos:

público sincronizado SQLiteDatabase getWritableDatabase ()

Cree y / o abra una base de datos que se usará para leer y escribir. Una vez abierto con éxito, la base de datos se almacena en caché, por lo que puede llamar a este método cada vez que necesite escribir en la base de datos.

La respuesta estuvo ahí todo el tiempo.

Lo publiqué en mayo en el Grupo de Google [android-developers]. Nunca recibí respuesta y no pude reproducir el problema hasta que uno de mis alumnos lo hizo la semana pasada. Pensé que lo publicaría aquí y vería si hacía sonar las campanas para cualquiera.

En uno de mis ejemplos de código, tengo el siguiente método:

static Cursor getAll(SQLiteDatabase db, String orderBy) { return(db.rawQuery("SELECT * FROM restaurants "+orderBy, null)); }

Cuando lo ejecuto, esporádicamente, obtengo esto:

05-01 14:45:05.849: ERROR/AndroidRuntime(1145): java.lang.IllegalStateException: attempt to acquire a reference on a close SQLiteClosable 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:31) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:56) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1118) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1092) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at apt.tutorial.Restaurant.getAll(Restaurant.java:14)

Esto no tiene ningún sentido para mí. La base de datos está definitivamente abierta. El SQLiteClosable es el SQLiteQuery creado por SQLiteQueryDriver , y no veo evidencia de que exista un grupo de objetos o algo así que pueda explicar cómo un "nuevo" SQLiteClosable ya está cerrado. El hecho de que sea esporádica (es decir, las mismas operaciones de IU a veces desencadenan la excepción, pero no siempre) sugiere algún tipo de grupo, condición de carrera, o algo así ... pero no estoy seguro de dónde.

¿Pensamientos?

¡Gracias!

ACTUALIZACIÓN : El código en cuestión es de los tutoriales de LunchList de mi libro de Tutoriales de Programación de Android . Está un poco extendido y no es muy adecuado para publicar directamente en SO. Puede descargar el código de ese libro desde el enlace de arriba si quiere echarle un vistazo. No recuerdo exactamente en qué edición del tutorial estaba trabajando el alumno en ese momento, aunque estaba en el rango Tutorial 12-Tutorial 16. Tenía muchas esperanzas de encontrar a alguien que había tropezado con este problema antes y que probablemente era el culpable. Estoy bastante seguro de que mi base de datos está abierta. ¡Gracias de nuevo!


He estado experimentando un problema similar, a pesar de seguir los consejos de Jarett . En mi caso, el problema ocurre con bastante regularidad en los cambios de orientación. Descubrí que, por alguna razón aún no he llegado al final, mi código genera dos AsyncTasks idénticas, casi simultáneas en un cambio de orientación (a diferencia de una sola cuando la actividad comienza normalmente). Estas tareas realizan la misma consulta de base de datos al mismo tiempo desde diferentes subprocesos.

Esta excepción (u ocasionalmente alguna otra SQLiteException) es el resultado. Por lo tanto, parece que este mensaje puede ser un síntoma de problemas de concurrencia, incluso si no es necesariamente la raíz del problema original publicado aquí.


SQLiteDatabase se cierra automáticamente bajo ciertas condiciones.

http://darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed-automatically.html

Los métodos getCount () y onMove () de Cursor activan una consulta real utilizando SQLiteQuery. Una vez que se obtienen todos los datos necesarios, SQLiteQuery reduce el recuento de referencias de la instancia de SQLiteDatabase. Cuando el recuento de referencias llega a 0, la base de datos se cierra.

Tenga en cuenta que la consulta se puede ejecutar de forma asincrónica y, en tal caso, getCount () puede devolver -1 si se invoca antes de que SQLiteQuery termine de preparar los datos.


Tuve el mismo problema durante unos días, y mi solución fue poner el método open () justo antes de mi consulta y método close () después de la operación de la base de datos. Se ve algo como esto.

open(); Cursor cur=db.query(DATABASE_TABLE_CON, null, null, null, null, null, " name ASC"); close(); return cur;

Funciona bien, pero me preocupa el costo de los recursos. No estoy seguro de estar gastando más recursos con toda esta base de datos de apertura y cierre antes de cualquier acción.