Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将数据库日志模式从删除迁移到WAL_Android_Sqlite_Android Sqlite - Fatal编程技术网

Android 将数据库日志模式从删除迁移到WAL

Android 将数据库日志模式从删除迁移到WAL,android,sqlite,android-sqlite,Android,Sqlite,Android Sqlite,我在我的应用程序中提供了一些导出/导入功能,现在我看到,如果旧的导出被导入到新的android版本中,这会产生问题,因为在许多运行android 9或更高版本的手机上,SQLite数据库确实使用了journal\u模式WAL,而不是在老式手机上使用的DELETE 信息/观察: 我没有在我的应用程序中设置手动日志模式(例如在SQLiteOpenHelper中) 并非所有android 9手机都启用了此功能(我的S9运行饼图仍然使用DELETE模式),因此在我的手机上恢复旧的备份效果非常好 在未使

我在我的应用程序中提供了一些导出/导入功能,现在我看到,如果旧的导出被导入到新的android版本中,这会产生问题,因为在许多运行android 9或更高版本的手机上,
SQLite
数据库确实使用了
journal\u模式
WAL
,而不是在老式手机上使用的
DELETE

信息/观察:

  • 我没有在我的应用程序中设置手动日志模式(例如在
    SQLiteOpenHelper
    中)
  • 并非所有android 9手机都启用了此功能(我的S9运行饼图仍然使用
    DELETE
    模式),因此在我的手机上恢复旧的备份效果非常好
  • 在未使用
    DELETE
    模式的手机上,还原的备份会使我的应用程序崩溃,因为数据库对我的应用程序来说似乎是空的,我对此并不在意。当然,关注空数据库并不能解决问题,因为我需要导入的数据
问题:

上述问题引出以下三个问题:

  • 如何确定当前手机默认使用的是
    WAL
    还是
    DELETE
  • 如何找到给定
    *.db
    文件的模式
  • 如何为给定的
    *.db
    文件更改此模式
我不想要的

我不想在我的应用程序中完全禁用
WAL
,我更喜欢一些基于迁移的解决方案

如何确定当前手机默认使用WAL还是DELETE

如果设备使用Android 9+,那么如果正确实现,它应该默认为WAL模式。但是,设备提供商可以提供自定义/遗留实现。因此,您需要按照如下所示/回答进行检查(实际上使用下面的方法不需要检查)

崩溃的原因可能是您没有备份wal模式激活时存在的其他-wal和-shm文件

在实际进行备份之前,我使用下面的代码

  • 显然DBConstants.DBNAME是数据库名
  • 数据库存储在默认位置(data/data/the_package/databases/
:-

这两种情况都适用,因为它通过检查数据库有效地消除了-wal-shm文件(清空它们)。因此,如果没有需要提交的未完成交易,则无需复制-wal-shm文件。这两种模式都适用

如何找出给定*.db文件的模式

csr=db.rawQuery(“PRAGMA journal_mode”,null)
是查询日志模式的行,还有返回true或false的SQLiteDatabase方法

关于:-

如何为给定的*.db文件更改此模式


如果使用Android SDK,则可以使用SQLiteDatabase方法,也可以通过设置,但请注意何时可以执行此操作的限制

如果我决定在所有android版本中禁用WAL模式,我所要做的就是:1)在我的下一个应用程序版本中,我确保我的数据库尚未打开,因此没有代码访问数据库2)我执行你上面发布的更长的代码块,这确保所有更改都写入数据库文件3)我使用
SQLiteOpenHelper
像往常一样打开数据库,并在配置数据库时在其中调用
disablewriteaheadloging
。这应该为所有设备保存,并且应该确保所有设备都在使用旧的日志模式,对吗?@prom85,是的,听起来正确。注意,上面的代码假设dbHelper连接已经关闭(关闭应该提交/检查点)。在应用程序重新启动后,它肯定会关闭,所以非常感谢你的帮助
private void checkpointIfWALEnabled(Context context) {
    final String TAG = "WALCHKPNT";
    Cursor csr;
    int wal_busy = -99, wal_log = -99, wal_checkpointed = -99;
    SQLiteDatabase db = SQLiteDatabase.openDatabase(context.getDatabasePath(DBConstants.DATABASE_NAME).getPath(),null,SQLiteDatabase.OPEN_READWRITE);
    csr = db.rawQuery("PRAGMA journal_mode",null);
    if (csr.moveToFirst()) {
        String mode = csr.getString(0);
        //Log.d(TAG, "Mode is " + mode);
        if (mode.toLowerCase().equals("wal")) {
            csr = db.rawQuery("PRAGMA wal_checkpoint",null);
            if (csr.moveToFirst()) {
                wal_busy = csr.getInt(0);
                wal_log = csr.getInt(1);
                wal_checkpointed = csr.getInt(2);
            }
            //Log.d(TAG,"Checkpoint pre checkpointing Busy = " + String.valueOf(wal_busy) + " LOG = " + String.valueOf(wal_log) + " CHECKPOINTED = " + String.valueOf(wal_checkpointed) );
            csr = db.rawQuery("PRAGMA wal_checkpoint(TRUNCATE)",null);
            csr.getCount();
            csr = db.rawQuery("PRAGMA wal_checkpoint",null);
            if (csr.moveToFirst()) {
                wal_busy = csr.getInt(0);
                wal_log = csr.getInt(1);
                wal_checkpointed = csr.getInt(2);
            }
            //Log.d(TAG,"Checkpoint post checkpointing Busy = " + String.valueOf(wal_busy) + " LOG = " + String.valueOf(wal_log) + " CHECKPOINTED = " + String.valueOf(wal_checkpointed) );
        }
    }
    csr.close();
    db.close();
}