Android.database.CursorWindowAllocationException: La asignación de ventana de cursor de 2048 kb falló incluso después de cerrar el cursor
Hay muchas preguntas sobre SO acerca de CursorWindowAllocatoinException:
- SQLite Android asignación de la ventana de cursor de 2048 kb falló
- No se pudo asignar CursorWindow
- Fuera de memoria al asignar cursores
- SQLite CursorWindowAllocationException crash
Todos ellos sugieren que el cursor debe cerrarse después de su uso. Pero eso no resolvió mi problema. Aquí está mi código:
- NoClassDefFoundError al usar greenDao
- Cómo utilizar FTS3 en SQLite
- Android cifrar / descifrar sqlite base de datos 100% seguro
- Persa / búsqueda árabe en sqlite android da mal resultado
- SQLiteAssetHelper NullPointerException sólo en algunos dispositivos
String query = "select serial from tbl1 union select serial from tbl2 union select serial from tbl3"; SQLiteDatabase db = null; Cursor cur = null; try { SettingsDatabaseHelper dal = new SettingsDatabaseHelper( c); db = dal.getReadableDatabase(); cur = db.rawQuery(query, null); int numRows = cur.getCount(); if (numRows > 0) { cur.moveToFirst(); int serialIdx = cur.getColumnIndexOrThrow("serial"); for (boolean hasItem = cur.moveToFirst(); hasItem; hasItem = cur .moveToNext()) { String serial = cur.getString(serialIdx); if (Validator.getInstance().isValidSerial(serial)) serials.add(serial); } } } finally { if (cur != null) cur.close(); if (db != null) db.close(); }
Ejecuto este método cada pocos segundos. Después de media hora, obtengo CursorWindowAllocationException
en int numRows=cur.getCount();
Y luego mi servicio se detiene.
Puesto que estoy cerrando el cursor, puede haber un problema con mi clase de ayuda. Aquí está el código:
public class SettingsDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "mydb.db"; private static final int DATABASE_VERSION = 1; private static final String TBL_CREATE="create table..."; public SettingsDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase database) { database.execSQL(TBL_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { onCreate(db); } }
¿Cómo puedo evitar que se lance esta excepción?
- SqliteException ocupado iOS / Android Xamarin MVVMCross
- No puede ver datos Sqlite con adaptador simple
- Persistencia de entidades bidireccionales con Green-DAO
- ContentProvider llamadas atómicas? Guardar en onPause, cargar en OnActivityCreated, datos antiguos
- BeginTransaction (), endTransaction () y setTransactionSuccessful (). ¿Qué hacen exactamente?
- ¿Por qué Androidite SQLite puede almacenar doble valor (java 8 bytes) en la columna de flotación
- Compartir base de datos SQLite entre 2 aplicaciones de Android?
- ¿Cómo puedo poner datos estáticos en una base de datos SQLite en Android?
Yo estaba consultando la base de datos de un servicio. Cuando lo hice de una actividad, el problema nunca se produjo de nuevo.
Junto con la consulta, estaba leyendo desde el puerto serie dentro del mismo servicio. Tal vez eso causó el problema. Sin embargo, cuando utilicé una actividad en lugar del servicio, el problema nunca volvió a ocurrir.
Tuve el mismo problema en mi aplicación al cargar más de 500 canciones de android media store.
Cerrar el cursor no resolverá su problema.
Debe utilizar AsyncTask. . Dentro del método doInBackground escribe el código para recuperar valores del cursor.
Public class CursorLoader extends AsyncTask {
@Override protected Void doInBackground(Void... params) { String query = "select serial from tbl1 union select serial from tbl2 union select serial from tbl3"; SQLiteDatabase db = null; Cursor cur = null; try { SettingsDatabaseHelper dal = new SettingsDatabaseHelper( c); db = dal.getReadableDatabase(); cur = db.rawQuery(query, null); int numRows = cur.getCount(); if (numRows > 0) { cur.moveToFirst(); int serialIdx = cur.getColumnIndexOrThrow("serial"); for (boolean hasItem = cur.moveToFirst(); hasItem; hasItem = cur .moveToNext()) { String serial = cur.getString(serialIdx); if (Validator.getInstance().isValidSerial(serial)) serials.add(serial); } } } finally { if (cur != null) cur.close(); if (db != null) db.close(); } return null; } @Override protected void onPreExecute() { } @Override protected void onPostExecute(Void result) { }
Tuve el mismo problema, mientras que estoy llamando a la BASE DE DATOS, en la clase de servicio usando siempre bucle.
Mi código era como:
service () { void run() { while(conditionisTrue) { db.getRecord(); //I remove this code from here and put it in the start of service c } } }
- Paquete enviado pero no puede recibir paquetes
- Cómo acceder a la lista de rechazo automático incorporada