Отключение записи в sqlite Write-Ahead в Android Pie - PullRequest
0 голосов
/ 06 декабря 2018

В Android Pie sqlite ведение журнала записи (WAL) включено по умолчанию.Это вызывает ошибки для моего существующего кода только в устройствах Pie.Мне не удалось отключить WAL с помощью SQLiteDatabase.disableWriteAheadLogging() или PRAGMA journal_mode из-за способа доступа к базе данных.Я хотел бы полностью отключить WAL с помощью параметра Android под названием db_compatibility_wal_supported :

Совместимость WAL (ведение журнала записи) для приложений

Кто-нибудьзнаете как это настроить?Я не знаю, можно ли программно изменить этот файл при запуске или изменить его вручную.


Дополнительная информация о проблеме

У меня есть база данных sqlite (20 МБ + / 250 КБзаписи) в моем приложении.Этот БД генерируется с использованием простой Java на моем сервере.Он содержит базу данных продуктов питания, и пользователь приложения может добавить в базу данных (и сервер обновляется).Это хранится в папке активов в Android.Во время первой установки база данных копируется из ресурсов в папку приложения, чтобы ее можно было записать, эффективно используя этот метод:

Копировать базу данных SQLite из папки активов

К сожалению, как только я начинаю запись в базу данных, используется SqlDroid wal, и таблицы, которые были в исходной базе данных, исчезли, и остались только все вновь созданные таблицы.Размер базы данных, однако, по-прежнему составляет 20 Мб +.Все ошибки базы данных связаны с отсутствием таблиц.Метод копирования и записи таблиц отлично работает в версиях Android до Pie.

Ответы [ 5 ]

0 голосов
/ 11 августа 2019

Если вы используете Room, у вас не будет прямого доступа к базе данных, но вы можете вместо этого установить режим журнала при создании / открытии базы данных:

db = Room.databaseBuilder(context, Database.class, "Database")
         .setJournalMode(JournalMode.TRUNCATE)
         .build();
0 голосов
/ 23 февраля 2019

Лучший и самый простой способ отключить режим WAL в вашей базе данных:

public class MyDbHelper extends SQLiteOpenHelper {

    //...

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

    //...
}

Таким образом, весь доступ к вашей базе данных будет отключен в режиме WAL.Столько, сколько вы открываете и закрываете несколько соединений в течение реализации вашего приложения

0 голосов
/ 13 декабря 2018

нельзя использовать SQLDroidDriver.ADDITONAL_DATABASE_FLAGS, просто потому, что нет константы , что могло бы отменить флаг ENABLE_WRITE_AHEAD_LOGGING.

WAL все еще можно отключить, создав любой из следующих сценариев:

a) установить флаг OPEN_READONLY (применяется в ситуациях, когда R/O доступ достаточен).

b) выполнить PRAGMA journal_mode=DELETE в качестве первого запроса, чтобы переопределить PRAGMA journal_mode=WAL.

c) устранить проблему с SQLDroidConnection.java , чтобы на уровне драйвера поддерживались .enableWriteAheadLogging() и .disableWriteAheadLogging().

0 голосов
/ 13 декабря 2018

Я наконец нашел ответ.Кажется, что ошибки базы данных, которые я получал, не имеют прямого отношения к WAL.Это связано с тем, что широко используемый код для копирования базы данных из ресурсов содержит ошибку, когда база данных остается открытой во время операции копирования.Это только начало вызывать проблему в Android P. Решение состоит в том, чтобы закрыть базу данных после того, как вы получите имя файла базы данных.

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

Подробнее об этом здесь: Android P - 'SQLite: НетТакая ошибка таблицы 'после копирования базы данных из активов

0 голосов
/ 09 декабря 2018

@ Rockvole, пожалуйста, поделитесь ошибкой, с которой вы столкнулись, и которая помогает нам найти подходящее решение.

В то же время я понимаю, что вы хотите закрыть WAL в пироге Android, и выиспользуют библиотеку SQLDroid для создания Sqlite DB.

Эта библиотека внутренне использует " SQLiteDatabase " для локального хранения данных, я думаю, вам нужно вызвать " SQLiteDatabase.disableWriteAheadLogging () " в " SQLiteDatabase"класс, в котором экземпляр БД создал имя пакета:" пакет org.sqldroid; "

или Получить внутренний экземпляр SQLiteDatabase и вызовите disableWriteAheadLogging ().

Второе решение - создать "config.xml" внутри папки значений и wirte "<bool name="db_compatibility_wal_supported">false</bool>", запустить и проверить его работу.

...