Предустановленная проблема с повреждением базы данных в приложении Android - PullRequest
4 голосов
/ 28 сентября 2011

У меня есть приложение для Android, которое начинается с загрузки большой базы данных на SD-карту (чуть более 50 МБ) в асинхронной задаче.Код для загрузки выглядит следующим образом.

HttpURLConnection conexion = (HttpURLConnection) url.openConnection();
if(filePath.exists() && filePath.length() > 10000.00)
{
    downloaded = (int) filePath.length();
    conexion.setRequestProperty("Range", "bytes=" + (filePath.length()) + "-");
}
else
    conexion.setRequestProperty("Range", "bytes=" + downloaded + "-");

conexion.setDoInput(true);
conexion.setDoOutput(true);
conexion.setUseCaches(false);
conexion.connect();

...

try {
    totalFileLength = lengthOfFile + downloaded;
    progressDialog.setMax(lengthOfFile + downloaded);
    // downlod the file
    input = new BufferedInputStream(conexion.getInputStream());
    output = (downloaded==0)? new FileOutputStream(filePath): new FileOutputStream(filePath,true);
    bout = new BufferedOutputStream(output, 1024);

    byte data[] = new byte[1024];

    while ((count = input.read(data, 0, 1024)) >= 0 && running) {
        downloaded += count;
        // publishing the progress....
        //onProgressUpdate((int)(downloaded*100/lengthOfFile));
        progressDialog.setProgress(downloaded);
        bout.write(data, 0, count);
    }
} catch (Exception e) {
    ...
} finally {
    try {
        input.close();
        bout.flush();
        bout.close();
    } catch(IOException e) {
        ...
    }
}

После полной загрузки файла я открываю базу данных и добавляю в нее таблицу.

try {
    myDbHelper.myDataBase.execSQL("CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)");
    success = true;
} catch (SQLException sqle) {
    throw sqle;
}

Теперь этот код прекрасно работает на каждом устройстве, на котором я его запускаю, но некоторые из моих пользователей получают эту ошибку в строке execSQL.Похоже, что он не работает только на Samsung Galaxy SII (не было ни одной жалобы и последующего отслеживания стека с этой ошибкой на любом другом телефоне), но я не совсем уверен, что это только этот телефон.

java.lang.RuntimeException: Unable to start activity ComponentInfo{net.daleroy.fungifieldguide/net.daleroy.fungifieldguide.activities.FungiFieldGuide}: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
       at android.app.ActivityThread.access$1500(ActivityThread.java:117)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:130)
       at android.app.ActivityThread.main(ActivityThread.java:3691)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:507)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
       at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)
       at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
       at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1904)
       at net.daleroy.fungifieldguide.services.MushroomService.MakeFavoriteTable(MushroomService.java:118)
       at net.daleroy.fungifieldguide.services.MushroomService.OpenDB(MushroomService.java:64)
       at net.daleroy.fungifieldguide.activities.FungiFieldGuide.onCreate(FungiFieldGuide.java:73)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)

Я получил копию базы данных, загруженную от пользователя с sgs2, и контрольная сумма файла отключена.Я также не вижу никаких данных или структуры данных в файле при открытии с помощью диспетчера sqlite (плагин firefox).Я позволил ему загрузить копию базы данных напрямую и поместить ее в свою папку данных, и приложение работает нормально.Так что проблема где-то в процессе загрузки.

Ответы [ 3 ]

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

Начиная с уровня API 9 (Android 2.3), вы можете использовать DownloadManager для обработки длительных загрузок HTTP:

Менеджер загрузок - это системная служба, которая обрабатывает долго работающие HTTP загрузки. Клиенты могут запросить загрузку URI в конкретный файл назначения. Менеджер закачек проведет загрузка в фоновом режиме, забота о HTTP-взаимодействиях и повторные попытки загрузки после сбоев или между изменениями подключения и система перезагружается.

Вот пример проекта, который демонстрирует использование DownloadManager: Пример Android DownloadManager .

Я думаю, что вы даже можете попытаться перенести DownloadManager в предыдущие версии Android (если вам необходимо их поддерживать). Его исходный код можно найти здесь: DownloadManager.java

1 голос
/ 28 сентября 2011

вы вызываете флеш и закрывает свой выходной поток?Вот так:

while ((count = input.read(data, 0, 1024)) >= 0 && running) {
    downloaded += count;
    progressDialog.setProgress(downloaded);
    bout.write(data, 0, count);
}
bout.flush();
bout.close();

Если бы не я, я бы начал с этого.Я скачал видео с похожим кодом и обнаружил, что для некоторых устройств и некоторых видео, не вызывающих функцию flush, происходит повреждение, что делает его недоступным для воспроизведения

0 голосов
/ 05 октября 2011

Вот еще один вопрос, который говорит об этом виде повреждения базы данных. Android - образ диска базы данных искажен .

Если вы не можете исправить базу данных, когда она находится в этом состоянии, возможно, вы можете попытаться загрузить ее снова, если и когда эта ошибка возникнет (при условии, что эта проблема встречается редко, и повторная загрузка базы данных может решить проблему).).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...