SQLiteDiskIOException en Android

Estamos recibiendo un gran número de errores de SQLiteDiskIOException en nuestra aplicación para Android, con trazas de pila similares a las siguientes:

 E/AndroidRuntime( 2252): Caused by: android.database.sqlite.SQLiteDiskIOException: disk I/O error E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteQuery.native_fill_window(Native Method) E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:75) E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:288) E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:269) E/AndroidRuntime( 2252): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:171) E/AndroidRuntime( 2252): at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:248) E/AndroidRuntime( 2252): at com.company.android.CActivity$QueryTask.doInBackground(CActivity.java:1660) 

Este hecho comenzó recientemente hace unas semanas, pero no hubo cambios significativos en la base de datos en la versión exacta en la que se inició el reporte de este problema. A pesar de tener (creo) los índices apropiados, esta excepción se ha informado más de lo que nos sentimos cómodos con las llamadas cursor.moveToFirst() después de completar la consulta, como se puede ver en el rastreo de la pila. Hasta ahora, hemos sido completamente incapaces de reproducir.

La consulta es algo complicada, con tres combinaciones de izquierda. A continuación se muestra una consulta representativa, con algunas columnas identificativas cambiadas para proteger a los inocentes.

 select distinct c._id as _id,c.type as type,c.name as name,c.slug as slug,c.description as description,c.extra1 as extra1,c.extra2 as extra2,c.extra3 as extra3,c.extra4 as extra4,c.extra5,c.extra6 as extra6,c.extra7 as extra7,c.extra8 as extra8, c.extra9 as extra9,c.sslug as sslug, c2.name as sname, p.type as prel, em.dS as dS,em.eS as eS from cse as c left join cse as c2 on c.sslug=c2.slug left join emed as em on c.slug=em.slug left join pre as p on c.sslug=p.slug where c.pslug='slug' AND c.user='user' AND c.csource='csource' order by c.type asc, c.extra6 desc, c.sortorder asc 

Otras fuentes han sugerido que estamos tratando de extraer demasiados datos, pero esto simplemente no es el caso. Los tres casos de usuario en los que hemos podido obtener bases de datos completas muestran: cse con <2000 entradas, emed con <150 entradas y pre con 0 o 7 entradas. Además, 'explain query plan' en la consulta indica que todas las uniones se realizan contra columnas indexadas.

En todos los casos hemos visto esto, el usuario estaba ejecutando Android 2.1 en una variedad de dispositivos (DROID, Hero, EVO, posiblemente otros). En particular, no hemos visto esto en un par de dispositivos G1 que tenemos, incluso cuando se cargan con otras aplicaciones.

Por último, la desinstalación y reinstalación ha probado ser exitosa en la limpieza del problema, aunque posiblemente sólo temporalmente.

Me temo que este problema es el resultado de la corrupción de datos en Android 2.1. ¿Alguien tiene sugerencias posibles de qué mirar? ¿Podría esto estar relacionado con este error de Android en SQLiteDatabaseCorruptException?

La orientación y las soluciones son muy apreciadas.

Parece que tienes varios problemas de roscado, un hilo intenta obtener los datos mientras otro uno o más intenta insertar algunos datos en tus tablas, porque la excepción es arrojada desde method (getCount).

También no se olvide; El cursor SQLite no está sincronizado internamente, por lo que si utiliza este cursor de varios subprocesos debe realizar su propio mecanismo de sincronización.

Tenemos un problema similar. Cuando se inicia la aplicación se produce un error. En el método onCreate comprobamos si existe alguna base de datos en la ruta de la aplicación. Si se produce alguna base de datos, invocamos dicho código

 public boolean createDataBase() throws IOException { boolean dbExist = checkDataBase(); if(dbExist) { //do nothing - database already exist } else { //By calling this method and empty database will be created into the default system path //of your application so we are gonna be able to overwrite that database with our database. this.getReadableDatabase(); } return dbExist; } private boolean checkDataBase() { SQLiteDatabase checkDB = null; try { String myPath = DATABASE_PATH + DATABASE_NAME; checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); } catch(SQLiteException e) { } if(checkDB != null) { checkDB.close(); } return checkDB != null ? true : false; } 

Y si no hay una base de datos (primera ejecución de la aplicación) lo copiamos de los recursos. Pero algunas veces se produce SQLiteDiskIOException y las llamadas de base de datos de recursos.

Una de las razones es como dijo Bassel Kh, multi thread problom, el otro es el db no está disponible, es decir. Db se elimina o sdcard es unavaliable.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.