web-dev-qa-db-ja.com

Android Pieでのsqlite先行書き込みロギングの無効化

Android Pie SQLite Write-Ahead Logging(WAL)がデフォルトで有効になっています。これにより、Pieデバイスでのみ既存のコードにエラーが発生します。SQLiteDatabase.disableWriteAheadLogging()を使用してWALを正常にオフにすることができませんまたはPRAGMA journal_modeデータベースへのアクセス方法が原因です。 Android設定と呼ばれるdb_compatibility_wal_supportedでWALを完全に無効にしたい:

アプリの互換性WAL(先読みログ)

誰もがこれを設定する方法を知っていますか?このファイルが起動時にプログラムで変更できるのか、手動で変更できるのかはわかりません。


問題の詳細

アプリにsqliteデータベース(20mb +/250kレコード)があります。このデータベースは、プレーンJavaを使用して生成されます。これには食品データベースが含まれており、アプリのユーザーはデータベースに追加できます(サーバーが更新されます)。これはアセットに保存されます。 Androidのフォルダー。最初のインストール時に、データベースはアセットからappフォルダーにコピーされるため、このメソッドを効果的に使用して、データベースに書き込むことができます。

アセットフォルダからSQLiteデータベースをコピー

残念ながら、SqlDroidを使用してデータベースへの書き込みを開始すると、walが有効になり、元のデータベースにあったテーブルが消えて、新しく作成されたテーブルのみが残ります。ただし、データベースのサイズはまだ20MB以上です。すべてのデータベースエラーは、不足しているテーブルが原因です。テーブルのコピーと書き込みのメソッドは、Pieより前のバージョンのAndroid=)で完全に機能します。

8
Rockvole

ようやく答えが見つかりました。私が受け取っていたデータベースエラーは、WALに直接関係していないようです。アセットからデータベースをコピーするために広く使用されているコードには、コピー操作中にデータベースが開いたままになっているというバグがあるためです。 Android Pで問題が発生し始めただけです。解決策は、データベースファイル名を取得した後でデータベースを閉じることです。

SQLiteDatabase destinationDatabase = sqLiteOpenHelper.getWritableDatabase();
String dbFileName=destinationDatabase.getPath();
destinationDatabase.close();
// Now write the destinationDatabase using the dbFileName

詳細はこちら: Android P-'SQLite:No Such Table Error' after database from asset from assets

0
Rockvole

データベースでWALモードを無効にする最も簡単な方法は次のとおりです。

public class MyDbHelper extends SQLiteOpenHelper {

    //...

    @Override
    public void onOpen(SQLiteDatabase db) {
        db.disableWriteAheadLogging();  // Here the solution
        super.onOpen(db);
    }

    //...
}

この方法では、データベースへのすべてのアクセスはWALモードが無効になります。アプリの実装全体で複数の接続を開いたり閉じたりするのと同じくらい

6
Carlos Henrique

@Rockvoleが直面しているエラーを共有してください。適切な解決策を見つけるのに役立ちます。

一方、私はあなたがそれを閉じたいと思っていることを理解します[〜#〜] wal [〜#〜] in Android pie and you are using "SQLDroid" lib to Sqlite DBを作成します。

このlibは、内部的に "SQLiteDatabase"を使用してデータをローカルに格納します。 "SQLiteDatabase"で "SQLiteDatabase.disableWriteAheadLogging()"を呼び出す必要があると思いますDBインスタンスがパッケージ名を作成したクラスは「package org.sqldroid; "

またはSQLiteDatabaseの内部インスタンスを取得し、disableWriteAheadLogging()を呼び出します。

2つ目の解決策は、valuesフォルダー内に「config.xml」を作成し、wirte "<bool name="db_compatibility_wal_supported">false</bool>"を実行して、その作業を確認します。

1
Parkash

Roomを使用している場合、データベースに直接アクセスすることはできませんが、代わりに、データベースを構築または開くときにジャーナルモードを設定できます。

db = Room.databaseBuilder(context, Database.class, "Database")
         .setJournalMode(JournalMode.TRUNCATE)
         .build();
0
Prof

フラグ__SQLDroidDriver.ADDITONAL_DATABASE_FLAGS_を無効にする constant がないため、_ENABLE_WRITE_AHEAD_LOGGING_を使用できません。

次のいずれかのシナリオを作成することで、WALを無効にすることができます。

a)フラグ_OPEN_READONLY_を設定します(_R/O_アクセスで十分な状況に適用されます)。

b)_PRAGMA journal_mode=DELETE_をオーバーライドするために、最初のクエリとして_PRAGMA journal_mode=WAL_を実行します。

c)ドライバーレベルで.enableWriteAheadLogging()および.disableWriteAheadLogging()をサポートするために、 SQLDroidConnection.Java に対して問題を報告します。

0
Martin Zeitler