9

在 Android Pie 中,sqlite 预写日志 (WAL) 默认已启用。这仅在 Pie 设备中导致我现有代码的错误。由于我访问数据库的方式,我SQLiteDatabase.disableWriteAheadLogging()无法成功关闭 WAL 。PRAGMA journal_mode我想使用名为db_compatibility_wal_supported的 Android 设置完全禁用 WAL :

应用程序的兼容性 WAL(预写日志记录)

有谁知道如何配置这个?我不知道这个文件是否可以在启动时以编程方式更改,或者是否可以手动更改。


有关问题的更多详细信息

我的应用程序中有一个 sqlite 数据库(20mb+ / 250k 记录)。这个数据库是在我的服务器上使用纯 java 生成的。它包含一个食物数据库,应用程序的用户可以添加到数据库中(并且服务器已更新)。这存储在 android 的 assets 文件夹中。在第一次安装期间,数据库从 assets 复制到 app 文件夹,以便可以写入,有效地使用以下方法:

从 assets 文件夹复制 SQLite 数据库

不幸的是,一旦我开始使用 SqlDroid 写入数据库,wal 就会启用,并且原始数据库中的表已经消失,只剩下任何新创建的表。然而,数据库的大小仍然是 20mb+。所有数据库错误都是由于缺少表。表格复制和写入方法在 Pie 之前的 Android 版本中完美运行。

4

5 回答 5

10

在数据库中禁用 WAL 模式的最佳和最简单的方法如下:

public class MyDbHelper extends SQLiteOpenHelper {

    //...

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

    //...
}

这样,对数据库的所有访问都将禁用 WAL 模式。就像您在应用程序的整个实施过程中打开和关闭多个连接一样

于 2019-02-23T00:26:22.877 回答
2

如果您使用的是 Room,您将无法直接访问数据库,但您可以在构建/打开数据库时设置日志模式:

db = Room.databaseBuilder(context, Database.class, "Database")
         .setJournalMode(JournalMode.TRUNCATE)
         .build();
于 2019-08-10T21:13:48.873 回答
2

一个不能使用SQLDroidDriver.ADDITONAL_DATABASE_FLAGS,仅仅因为没有可用的常量,这会否定 flag ENABLE_WRITE_AHEAD_LOGGING

WAL 仍然可以通过创建以下任一场景来禁用:

a) 设置标志OPEN_READONLY(适用于R/O访问足够的情况)。

b)PRAGMA journal_mode=DELETE作为第一个查询运行,以覆盖PRAGMA journal_mode=WAL.

c) 提交针对SQLDroidConnection.java的问题,以便在驱动程序级别获得.enableWriteAheadLogging()并支持。.disableWriteAheadLogging()

于 2018-12-13T02:38:59.900 回答
1

@Rockvole 请分享您面临的错误,这有助于我们找到合适的解决方案。

同时,我知道您想在 android pie 中关闭该WAL,并且您正在使用“SQLDroid”库来创建 Sqlite DB。

该库在内部使用“ SQLiteDatabase ”在本地存储数据,我认为您需要在“ SQLiteDatabase ”类中调用“ SQLiteDatabase.disableWriteAheadLogging() ”,其中数据库实例创建包名称为“ package org.sqldroid;

获取内部 SQLiteDatabase 实例并调用 disableWriteAheadLogging()。

第二种解决方案是在 values 文件夹中创建“config.xml”,"<bool name="db_compatibility_wal_supported">false</bool>"然后运行并检查其工作。

于 2018-12-09T05:36:48.117 回答
0

我终于找到了答案。我收到的数据库错误似乎与 WAL 没有直接关系。这是因为广泛使用的从资产复制数据库的代码中存在一个错误,即在复制操作期间数据库处于打开状态。这只是在Android P中开始引起问题。解决方案是在获取数据库文件名后关闭数据库。

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

这在这里更详细: Android P - 从资产复制数据库后的“SQLite:没有这样的表错误”

于 2018-12-13T18:48:15.693 回答