2

我有一个具有备份和恢复功能的应用程序。单击要备份的按钮会将 db 文件复制到外部存储。单击恢复按钮将从外部存储中获取文件(如果存在)并将其复制到应用程序中,并用备份数据库文件覆盖现有数据库。

我在对表执行更新时遇到了这个问题。用数据更新表后,更新数据的数据库不会复制到外部存储中,或者如果我在更新后尝试恢复,则不会复制文件。

保存项目时,打开数据库,然后调用以下函数执行更新,然后关闭数据库。

public void saveItem(int ItemID, int ItemNumber, String itemnote) 

{

        ContentValues args = new ContentValues();
        args.put("ItemNote", itemnote);
    mDb.update("Items", args, "ItemID =" + Item+" and ItemNumber ="+ItemNumber, null);

}

更新发生后,是什么阻止了 db 文件被复制?

我正在使用以下代码将数据库备份导入应用程序。同样,这一切都在执行更新语句之前起作用。提前致谢。

importdb.setOnClickListener(new View.OnClickListener(){ public void onClick(View arg0) {

            final File DATA_DIRECTORY_DATABASE = getDatabasePath("MyDB");

            final File DATABASE_DIRECTORY = new File(Environment.getExternalStorageDirectory(),"/MyApp");
            final File IMPORT_FILE = new File(DATABASE_DIRECTORY,"MyDB");

            File exportFile = DATA_DIRECTORY_DATABASE;

            File importFile = IMPORT_FILE;


            try {
                exportFile.createNewFile();
                copyFile(importFile, exportFile);
                Log.i("Import", "Succesfull");

            } catch (IOException e) {
                e.printStackTrace();

            }       




        }

    });

private static void copyFile(File src, File dst) throws IOException {
    FileChannel inChannel = new FileInputStream(src).getChannel();
    FileChannel outChannel = new FileOutputStream(dst).getChannel();
    try {
        inChannel.transferTo(0, inChannel.size(), outChannel);
    } finally {
        if (inChannel != null)
            inChannel.close();
        if (outChannel != null)
            outChannel.close();
    }
}
4

3 回答 3

0

我认为数据库版本没有改变,这就是代码无法正常工作的原因。

于 2013-01-25T05:57:46.010 回答
0

如果数据库连接没有关闭,那么数据库文件可能仍然被 SQLite 锁定;因此阻止其复制。

如果您使用多个线程,那么即使关闭数据库连接,SQLite 也有可能在第二个线程尝试复制它之前没有时间关闭数据库并释放锁。

于 2013-01-25T20:54:10.230 回答
0

在对不同设备进行大量测试并查看日志文件之后。发现在某些设备上,数据库处于预写日志记录模式 (wal)。这不是所有设备,但在我的一个测试设备 HTC Droid Incredible 上,启用了 wal,而在 kindle fire 上未启用 wal。

在未启用 wal 的设备上,没有问题。在带有 wal 的设备上,数据的导入和导出无法正常工作,因为实际的 db 文件不是最新的,因为任何更改都驻留在 wal 文件中,并且在 wal 的检查点被命中之前不会提交到 db 文件。

为了确保导入和导出功能正常工作,我需要数据库包含最新的信息。为此,需要运行 sqlite 语句来执行 wal 检查点,该检查点会将所有信息提交到 db 文件。

在运行导出或导入功能之前,执行以下 sqlite 命令以启动检查点并清除 wal 并将更改提交到数据库。

PRAGMA wal_checkpoint

调用检查点后,功能正常工作

于 2013-01-28T00:34:28.337 回答