0

WAL (先行書き込みログ) が有効になっているこれらの少数の Android デバイスで、データベースのバックアップ/復元に多くの問題があります。そのようなデータベースが作成された後、それをオフにすることは可能ですか?

私の考えは:

1.) 古い Android デバイスでこれを機能させるラッパー:

public class SQLiteDatabaseWalWrapper {

    private boolean        available;
    private Method         disableWriteAheadLogging;
    private Method         enableWriteAheadLogging;
    private Method         isWriteAheadLoggingEnabled;
    private SQLiteDatabase sqliteDatabase;

    public SQLiteDatabaseWalWrapper(final SQLiteDatabase sqliteDatabase) {
        this.sqliteDatabase = sqliteDatabase;

        available = false;

        try {
            disableWriteAheadLogging = SQLiteDatabase.class.getMethod("disableWriteAheadLogging");
            enableWriteAheadLogging = SQLiteDatabase.class.getMethod("enableWriteAheadLogging");
            isWriteAheadLoggingEnabled = SQLiteDatabase.class.getMethod("isWriteAheadLoggingEnabled");

            available = true;
        } catch (NoSuchMethodException noSuchMethodException) {
        }
    }

    public boolean checkAvailable() {
        return available;
    }

    public void disableWriteAheadLogging() {
        if (disableWriteAheadLogging != null) {
            try {
                disableWriteAheadLogging.invoke(sqliteDatabase);
            } catch (IllegalAccessException illegalAccessException) {
            } catch (IllegalArgumentException illegalArgumentException) {
            } catch (InvocationTargetException invocationTargetException) {
            }
        }
    }

    public boolean enableWriteAheadLogging() {
        boolean result = false;

        if (enableWriteAheadLogging != null) {
            try {
                result = (Boolean) enableWriteAheadLogging.invoke(sqliteDatabase);
            } catch (IllegalAccessException illegalAccessException) {
            } catch (IllegalArgumentException illegalArgumentException) {
            } catch (InvocationTargetException invocationTargetException) {
            }
        }

        return result;
    }

    public boolean isWriteAheadLoggingEnabled() {
        boolean result = false;

        if (isWriteAheadLoggingEnabled != null) {
            try {
                result = (Boolean) isWriteAheadLoggingEnabled.invoke(sqliteDatabase);
            } catch (IllegalAccessException illegalAccessException) {
            } catch (IllegalArgumentException illegalArgumentException) {
            } catch (InvocationTargetException invocationTargetException) {
            }
        }

        return result;
    }
}

2.) AsyncTask を使用した拡張アプリケーション内で、FULL チェックポイントを発行し、WAL をオフに切り替えます。

public class MyApplication extends Application {

    private class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {

        @Override
        protected Boolean doInBackground(final Void... voids) {
            // Make a full checkpoint
            sqliteDatabase.execSQL("PRAGMA wal_checkpoint(FULL);");

            // switch WAL off
            sqliteDatabaseWalWrapper.disableWriteAheadLogging();
        }

        @Override
        protected void onPostExecute(final Boolean result) {
        }
    }

    private Context                  context;
    private SQLiteDatabase           sqliteDatabase;
    private SQLiteDatabaseWalWrapper sqliteDatabaseWalWrapper;
    private MySQLiteOpenHelper       sqliteOpenHelper;
    private MyAsyncTask              task;

    @Override
    public void onCreate() {
        super.onCreate();

        context = getApplicationContext();

        sqliteOpenHelper = new MySQLiteOpenHelper(context);
        if (sqliteOpenHelper != null) {
            sqliteDatabase = sqliteOpenHelper.getWritableDatabase();
            if (sqliteDatabase != null) {

                if (Build.VERSION.SDK_INT >= 16) {
                    sqliteDatabaseWalWrapper = new SQLiteDatabaseWalWrapper(sqliteDatabase);
                    if (sqliteDatabaseWalWrapper != null && sqliteDatabaseWalWrapper.checkAvailable() && sqliteDatabaseWalWrapper.isWriteAheadLoggingEnabled()) {
                        task = new MyAsyncTask();
                        task.execute();
                    }
                }
            }
        }
    }

    @Override
    public void onTerminate() {
        if (sqliteDatabase != null) {
            sqliteDatabase.close();
        }

        if (sqliteOpenHelper != null) {
            sqliteOpenHelper.close();
        }

        super.onTerminate();
    }
}

これは機能しますか?これにより、SQLite が WAL 対応データベースで作成するさまざまな追加ファイルが削除されますか? これは、Android ドキュメントで説明されている単一のデータベース ファイルに戻るのでしょうか?

4

3 に答える 3

1

データベースで実行PRAGMA journal_mode=DELETEすると、Walモードが削除され、通常の操作方法に戻るはずです。

ここに完全なドキュメント:http ://www.sqlite.org/wal.html

于 2013-01-29T11:04:51.987 に答える
0

プログラムで、WAL モードを有効または無効にすることができます。APIレベル11から存在しています

詳細については、このドキュメントを参照してください

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging()

于 2013-10-12T12:10:48.303 に答える