在Android Pie中禁用sqlite预写日志记录

时间:2018-12-06 20:29:28

标签: android sqlite wal sqldroid

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

Compatibility WAL (Write-Ahead Logging) for Apps

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


有关该问题的更多详细信息

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

Copy SQLite database from assets folder

不幸的是,一旦我开始使用SqlDroid写入数据库,就会启用wal并且原始db中的表消失,仅保留任何新创建的表。但是,数据库的大小仍为20mb +。所有数据库错误均归因于缺少表。 表格复制和写入方法可以在Pie之前的Android版本中完美运行。

5 个答案:

答案 0 :(得分:2)

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

public class MyDbHelper extends SQLiteOpenHelper {

    //...

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

    //...
}

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

答案 1 :(得分:1)

@Rockvole,请分享您遇到的错误,以帮助我们找到适当的解决方案。

同时,我了解到您想在Android Pie中关闭该 WAL ,并且您正在使用“ SQLDroid” lib创建Sqlite DB。

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

获取内部SQLiteDatabase实例 ,然后调用disableWriteAheadLogging()。

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

答案 2 :(得分:0)

一个人不能使用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)针对SQLDroidConnection.java提出问题, 以便在驱动程序级别上支持.enableWriteAheadLogging().disableWriteAheadLogging()

答案 3 :(得分:0)

我终于找到了答案。看来我收到的数据库错误与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 copying database from assets

答案 4 :(得分:0)

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

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