2011-02-22 19 views
14

Nelle ultime due settimane, senza rilasciare un aggiornamento alla mia app, ho iniziato a ricevere un sacco di report con database danneggiati. Di seguito è riportato lo stacktrace. Android non può aprire il database e nemmeno il programma sqlite-manager sul mio computer. Tuttavia, il gestore di SQLite-addon di Firefox potrebbe aprirlo. Dopo aver eseguito il comando "database compatto", il database è stato risolto e potrei aprirlo in Android. C'è un modo per fare qualcosa di simile nella mia app? Il grosso problema è che non riesco nemmeno a tentare di aprire il database, perché le versioni più recenti di Android elimineranno e sostituiranno immediatamente il database, come puoi vedere nello stacktrace sottostante. Le dichiarazioni di PRAGMA possono essere eseguite in qualche modo senza aprire il database?corrotto, ma può essere aperto in SQLite Manager. Recuperabile?

saluti,

02-22 09:55:20.245: ERROR/Database(5382): CREATE TABLE android_metadata failed 
02-22 09:55:20.245: ERROR/Database(5382): Failed to setLocale() when constructing, closing the database 
02-22 09:55:20.245: ERROR/Database(5382): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1950) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1818) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) 

02-22 09:55:20.245: ERROR/Database(5382): Deleting and re-creating corrupt database /mnt/sdcard/myapp/backup.sqlite 
02-22 09:55:20.245: ERROR/Database(5382): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1950) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1818) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540) 
02-22 09:55:20.245: ERROR/Database(5382):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) 

EDIT: ho Manager per aprire il database in questo modo:

db = SQLiteDatabase.openDatabase(database, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 

Ma quando ho eseguito questo:

String sqlQuery = "pragma integrity_check"; 
db.execSQL(sqlQuery); 

ottengo questo:

ERROR/AndroidRuntime(9144): Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: pragma integrity_check 

Edit2: Mi sono reso conto che passare l'aspirapolvere al database risolve il problema. Ma se vuoto dall'interno della mia app, con exeSQL ("vuoto"), non aiuta. Perchè è questo? : '(

risposta

1

la buona strada canonica per ripristinare un database danneggiato è quello di scaricare fuori come SQL e poi leggerlo di nuovo in un nuovo database E' morto facile con lo strumento sqlite:.

sqlite in.db .dump | sqlite out.db 

. ..ma, naturalmente, è necessario farlo in codice, e davvero non so se .dump è disponibile da qualsiasi luogo.

Ti suggerirei che potresti voler vedere come si sta corrompendo in primo luogo --- SQLite è sempre stato solido per me, anche se l'ho usato solo nella memoria interna Posso controllare il filesystem FAT per vedere se è corrotto? Ho visto, e. g., fotocamere digitali che maneggiano il filesystem su schede in vari modi oscuri ...

0

Nella tua app chiudi il database prima di uscire dall'attività? Guarda il logcat e controlla se ci sono errori o avvisi quando esegui la tua app.

1

Android che cancella il database è un issue effettivamente.

Ho appena realizzato che una soluzione potrebbe essere quella di utilizzare SQLJet anziché l'implementazione predefinita di SQL SQL.
Come il nome non suggerisce, SQLJet è un client SQLite Java open source e funziona su Android.

+0

Grazie, sembra davvero interessante! – pgsandstrom

+0

@Nicolas Raoul Potresti spiegare come SQLJet risolverà il problema dell'OP/impedirlo? Sono curioso, visto che sto avendo gli stessi problemi dell'OP :) – AgentKnopf

+0

SQLite non ha questo bug –