База данных Android повреждена, но может открыться в SQLite Manager.Извлекаемые? - PullRequest
14 голосов
/ 22 февраля 2011

В последние две недели, не выпуская обновления для моего приложения, я начал получать кучу отчетов с поврежденными базами данных. Ниже приведена трассировка стека. Android не может открыть базу данных, как и программа sqlite-manager на моем компьютере. Однако, дополнение менеджера SQLite к Firefox может открыть его. После запуска команды «компактная база данных» база данных была исправлена, и я смог открыть ее в Android. Есть ли способ сделать что-то подобное в моем приложении? Большая проблема заключается в том, что я даже не могу попытаться открыть базу данных, потому что более новые версии Android будут немедленно удалять и заменять базу данных, как вы можете видеть на трассировке стека ниже. Можно ли каким-либо образом выполнять заявления PRAGMA, не открывая базу данных?

С уважением,

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)

Редактировать: я менеджер, чтобы открыть базу данных, как это:

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

Но когда я запускаю это:

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

Я понял:

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

Edit2: я понял, что очистка базы данных устраняет проблему. Но если я пропускаю пылесос внутри своего приложения с помощью exeSQL («вакуум»), это не поможет. Почему это? : '(

Ответы [ 3 ]

1 голос
/ 14 октября 2011

Android удаление базы данных - это действительно проблема .

Я только что понял, что может быть решение использовать SQLJet вместо стандартной реализации SQLite для Android.
Как видно из названия, SQLJet - это клиент Javaite с открытым исходным кодом, работающий на Android.

1 голос
/ 28 февраля 2011

Хороший канонический способ восстановить поврежденную базу данных - выгрузить ее как SQL и затем прочитать обратно в новую базу данных. Это очень просто с помощью инструмента sqlite:

sqlite in.db .dump | sqlite out.db

... но, конечно, вам нужно сделать это в коде, и я действительно не знаю, доступен ли .dump где-либо.

Я бы предположил, что вы, возможно, захотите узнать, как он в первую очередь искажается - SQLite всегда был для меня надежным, хотя я когда-либо использовал его только во внутреннем хранилище. Можете ли вы проверить файловую систему FAT, чтобы увидеть, не повреждена ли она? Я видел, например, цифровые камеры, которые будут тщательно искажать файловую систему на картах различными неясными способами ...

0 голосов
/ 07 марта 2011

В вашем приложении вы закрываете базу данных перед выходом из активности? Посмотрите logcat и проверьте, есть ли какие-либо ошибки или предупреждения при запуске приложения.

...