SQLite Android asignación de la ventana de cursor de 2048 kb falló

Tengo una rutina que ejecuta diferentes consultas en una base de datos SQLite muchas veces por segundo. Después de un tiempo me gustaría obtener el error

"android.database.CursorWindowAllocationException: - Cursor window allocation of 2048 kb failed. # Open Cursors = " aparece en LogCat.

Tuve el uso de la memoria de registro de aplicación, y de hecho cuando el uso alcanza un cierto límite, obtengo este error, lo que implica que se agota. Mi intuición me dice que el motor de base de datos está creando un nuevo buffer (CursorWindow) cada vez que ejecuto una consulta, y aunque marca los cursores .close (), ni el recolector de basura ni SQLiteDatabase.releaseMemory() son lo suficientemente rápidos en Liberando memoria. Creo que la solución puede mentir en "forzar" a la base de datos para escribir siempre en el mismo búfer, y no crear otros nuevos, pero no he podido encontrar una manera de hacer esto. He intentado instantiating mi propio CursorWindow, y he intentado fijarlo a y SQLiteCursor en ninguna utilidad.

¿Algunas ideas?

EDIT: ejemplo de código de ejemplo de @GrahamBorland:

 public static CursorWindow cursorWindow = new CursorWindow("cursorWindow"); public static SQLiteCursor sqlCursor; public static void getItemsVisibleArea(GeoPoint mapCenter, int latSpan, int lonSpan) { query = "SELECT * FROM Items"; //would be more complex in real code sqlCursor = (SQLiteCursor)db.rawQuery(query, null); sqlCursor.setWindow(cursorWindow); } 

Idealmente, me gustaría poder .setWindow() antes de dar una nueva consulta, y tener los datos puestos en el mismo CursorWindow cada vez que recibo nuevos datos.

La mayoría de las veces la causa de este error son cursores no cerrados. Asegúrese de cerrar todos los cursores después de usarlos (incluso en el caso de un error).

 Cursor cursor = null; try { cursor = db.query(... // do some work with the cursor here. } finally { // this gets called even if there is an exception somewhere above if(cursor != null) cursor.close(); } 

Si tiene que cavar a través de una cantidad significativa de código SQL, puede acelerar su depuración poniendo el fragmento de código siguiente en su MainActivity para habilitar StrictMode. Si se detectan objetos de base de datos filtrados, su aplicación se bloqueará con información de registro que resaltará exactamente dónde se encuentra su pérdida. Esto me ayudó a localizar un cursor pícaro en cuestión de minutos.

 @Override protected void onCreate(Bundle savedInstanceState) { if (BuildConfig.DEBUG) { StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } super.onCreate(savedInstanceState); ... ... 

Acabo de experimentar este problema – y la respuesta sugerida de no cerrar el cursor mientras válido, no era cómo lo arreglé. Mi problema era cerrar la base de datos cuando SQLite estaba tratando de repoblar su cursor. Abriría la base de datos, consulta la base de datos para conseguir un cursor a un sistema de datos, cierra la base de datos e itera sobre el cursor. Me di cuenta cada vez que golpeo un cierto registro en ese cursor, mi aplicación se bloquea con este mismo error en OP.

Supongo que para que el cursor acceda a ciertos registros, necesita volver a consultar la base de datos y si está cerrada, lanzará este error. Lo arreglé no cerrando la base de datos hasta que había completado todo el trabajo que necesitaba.

  • Java - java.lang.IllegalStateException: No se pudo leer la fila 0, col -1 de CursorWindow
  • ¿Cómo manejas los registros de antememoria de caché en la aplicación para móviles
  • ¿Cuál es el equivalente más cercano a una variable Session / Cookie en Android?
  • Cómo proteger una base de datos sqlite pre hecho en android?
  • ¿Cómo puedo mantener mi base de datos en una tarjeta SD y utilizar ORMLite?
  • Intel XDK: Conexión de la aplicación móvil a una base de datos
  • por qué c.moveToFirst () no saltará la primera fila
  • Administración de conexiones SQLite en Android
  • Cómo implementar Exportar sqlite Para sobresalir / archivo csv en android?
  • ¿Cómo mostrar los datos de la base de datos en un RecyclerView con alto rendimiento?
  • Android: actualizar la versión de la base de datos y agregar nueva tabla
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.