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

Roc*_*ole 8 sqlite android wal sqldroid

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

适用于应用程序的兼容性WAL(预写日志)

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


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

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

从资产文件夹复制SQLite数据库

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

Car*_*que 5

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

public class MyDbHelper extends SQLiteOpenHelper {

    //...

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

    //...
}
Run Code Online (Sandbox Code Playgroud)

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


Roc*_*ole 0

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

SQLiteDatabase destinationDatabase = sqLiteOpenHelper.getWritableDatabase();
String dbFileName=destinationDatabase.getPath();
destinationDatabase.close();
// Now write the destinationDatabase using the dbFileName
Run Code Online (Sandbox Code Playgroud)

这里有更多详细信息: Android P - 'SQLite: No Such Table Error' after copying database from assets

  • 这个答案根本与问题不符。https://meta.stackexchange.com/questions/16065/how-does-the-bounty-system-work (2认同)