数据库导入和导出在Android Pie中不起作用 [英] Database Import and Export not working in Android Pie

查看:137
本文介绍了数据库导入和导出在Android Pie中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是导入和导出SQLite数据库的工作方法.在除Android Pie外的所有android版本中,其工作情况都很好.当我尝试导入Android Pie时,它显示成功的Toast,但未还原数据库.谁能帮我解决Android Pie(API 28)问题.

Below is the working method to Import and Export SQLite database. Its Working just fine in all android versions excluding Android Pie. When I am trying to import in Android pie, it shows successful toast but database is not being restored. Can anybody help me workaround in Android Pie(API 28).

private void importDB() {

    try {
        File sd = Environment.getExternalStorageDirectory();
        File cur_db_pat = new File(this.getDatabasePath(DATABASE_NAME).getAbsolutePath());

        if (sd.canWrite()) {
            String backupDBPath = bac_dir_nam +"/" + DATABASE_NAME;
            File currentDB = new File(sd, backupDBPath);

            FileChannel src = new FileInputStream(currentDB).getChannel();
            FileChannel dst = new FileOutputStream(cur_db_pat).getChannel();
            dst.transferFrom(src, 0, src.size());
            src.close();
            dst.close();
            Toast.makeText(getBaseContext(), cur_db_pat.toString(),
                    Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {

        Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG)
                .show();

    }
}

private void exportDB() {

    try {
        File sd = Environment.getExternalStorageDirectory();
        File cur_db_pat = new File(this.getDatabasePath(DATABASE_NAME).getAbsolutePath());

        if (sd.canWrite()) {
            String backupDBPath = bac_dir_nam+"/" + DATABASE_NAME;
            File backupDB = new File(sd, backupDBPath);

            FileChannel src = new FileInputStream(cur_db_pat).getChannel();
            FileChannel dst = new FileOutputStream(backupDB).getChannel();
            dst.transferFrom(src, 0, src.size());
            src.close();
            dst.close();
            Toast.makeText(getBaseContext(), backupDB.toString(),
                    Toast.LENGTH_LONG).show();

        }
    } catch (Exception e) {

        Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG)
                .show();

    }
}

我对文件系统没有太多经验.因此,举个例子会很有帮助.

I don't have much experience with file system. So an example would help a lot.

推荐答案

在Android Pie +中,SQLite已更改为默认设置,以使用通常更有效的预写日志记录( WAL )代替日记模式.

In Android Pie+ SQLite has changed to default to using the generally more efficient Write Ahead Logging (WAL) instead of Journal mode.

因此,将有两个文件与数据库同名,但后缀为 -shm (共享内存文件)和 -wal (预写日志),并且我认为它们的存在是导致问题的原因. SQLite使用的临时文件(请参阅2.2和2.3)

As such there will be two files with the same name as the database but suffixed with -shm (shared memory file) and -wal (write ahead log) and their presence is what I believe causes the issue(s). Temporary Files Used By SQLite (see 2.2 and 2.3)

一种解决方法是使用SQliteDatabase disableWriteAheadLogging 方法禁用预写日志记录,而先前的方法将像以前一样工作,但是日志模式的效率较低.

One fix would be to disable Write Ahead Logging using use the SQliteDatabase disableWriteAheadLogging method and the previous method would work as before but with the less efficient journal mode.

  • (如果使用 SQliteOpenHelper 的子类,然后重写 onConfigure 方法以调用此方法.)
  • (if using a subclass of SQliteOpenHelper then override the onConfigure method to invoke this method. ) disableWriteAheadLogging.

另一个解决方法是还原时删除这两个文件.为了避免潜在的损坏,必须在进行备份之前确保对数据库进行适当的检查.参见 PRAGMA检查点;

Another fix is to delete these two files when restoring. To avoid the potential for corruption you have to ensure that the database was adequately checkpointed before making the backup. see PRAGMA checkpoint;

以下是还原时删除这两个文件的摘要(请注意,假定已使用足够的检查点进行了备份):-

The following is a snippet that deletes these two files when restoring (noting that the backup is assumed to have been taken with adequate checkpointing):-

                    // Added for Android 9+ to delete shm and wal file if they exist
                    File dbshm = new File(dbfile.getPath() + "-shm");
                    File dbwal = new File(dbfile.getPath()+ "-wal");
                    if (dbshm.exists()) {
                        dbshm.delete();
                    }
                    if (dbwal.exists()) {
                        dbwal.delete();
                    }

另一种解决方法是另外备份并随后还原-shm和-wal文件.

Another fix would be to additionally backup and subsequently restore the -shm and -wal files.

您可能还希望考虑在导入/还原时重命名原始文件,在复制新文件后检查新文件的潜在好处(例如,使用

You may also wish considering the potential benefits of renaming the original files when importing/restoring, checking the new files after they have been copied (e.g. using PRAGMA integrity_check;) if the results indicat no issues then delete the renamed original files, otherwise delete the imported files and rename the original files to their original name, indicating that the import failed.

这篇关于数据库导入和导出在Android Pie中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆