4

以下のコードを使用して、事前設定された (ORMLite) データベースをアセットからインポートしています。

これは、Galaxy Note 10.1 を除いて、複数のデバイスで問題なく動作します。ここでは、操作が終了した後に DB を閉じると例外が発生します。

「エラー コード = 11、メッセージ = 行でデータベースが破損しています ....」

デバイスからデータベースをダウンロードして SqliteBrowser で開くと、すべて問題ないようです。何か案は ?

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

// {....}

public void importDB() {

    InputStream is = context.getAssets().open("DBName.db");

    try {
        close();
        FileOutputStream os = new FileOutputStream(new File(Environment.getDataDirectory(), dbPath));
        try {
            byte[] buffer = new byte[4096];
            for (int n; (n = is.read(buffer)) != -1;) {
                os.write(buffer, 0, n);
            }
        } finally {
            os.close();
        }
    } finally {
        is.close();
    }
    getWritableDatabase().close();
}

エラー:

I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database         corruption at line 48171 of [ed759d5a9e], db=/data/data/app_name/databases/DBName_db
I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database disk image is malformed, db=/data/data/app_name/databases/DBName_db
E/SqliteDatabaseCpp(684): sqlite3_exec - Failed to set synchronous mode = 1(Normal) 
I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database corruption at line 48171 of [ed759d5a9e], db=/data/data/app_name/databases/DBName_db
I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database disk image is malformed, db=/data/data/app_name/databases/DBName_db
E/SqliteDatabaseCpp(684): CREATE TABLE android_metadata failed
E/DefaultDatabaseErrorHandler(684): Corruption reported by sqlite on database: /data/data/app.name/databases/DBName.db
E/DefaultDatabaseErrorHandler(684): deleting the database file: /data/data/app.name/databases/DBName.db
4

2 に答える 2

0

logcat の出力からわかるように、DatabaseErrorHandler のカスタム実装を提供しておらず、暗黙のハンドラー (DefaultDatabaseErrorHandler) は単に破損したデータベースを削除します。DefaultDatabaseErrorHandler の実装を使用する必要があります

PRAGMA integrity_check を実行する必要があります。復元されたデータベース上。これは通常、文字列「ok」を返します。それ以外の場合は文字列を解析できます。たとえば、インデックスが見つかった場合は、削除して再作成できます。

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    public MySQLiteOpenHelper(final Context context) {
        super(context, DB_NAME, null, DATABASE_VERSION, new DatabaseErrorHandler() {
            @Override
            public void onCorruption(SQLiteDatabase db) {
                //your code
            }
        });
    }

    // {....}

}
于 2018-01-08T12:33:33.647 に答える