2

バックアップと復元機能を備えたアプリがあります。ボタンをクリックしてバックアップすると、dbファイルが外部ストレージにコピーされます。復元ボタンをクリックすると、ファイルが外部ストレージ(存在する場合)から取得され、アプリにコピーされ、既存のデータベースがバックアップデータベースファイルで上書きされます。

テーブルで更新を実行すると、この問題が発生しました。テーブルがデータで更新された後、更新されたデータを含むデータベースが外部ストレージにコピーされないか、更新が行われた後に復元しようとすると、ファイルがコピーされません。

アイテムが保存されると、dbが開かれ、次の関数が呼び出されて更新が実行され、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ファイルがコピーされない原因は何ですか?

次のコードを使用して、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 によってロックされたままになっている可能性があります。したがって、そのコピーをブロックします。

複数のスレッドを使用している場合、データベース接続を閉じても、2 番目のスレッドがデータベースをコピーしようとする前に、SQLite がデータベースを閉じてロックを解放する時間がなかった可能性もあります。

于 2013-01-25T20:54:10.230 に答える
0

さまざまなデバイスで多くのテストを行い、ログ ファイルを確認した後。一部のデバイスで、データベースが先行書き込みログ モード (wal) になっていることが判明しました。これはすべてのデバイスではありませんが、私のテスト デバイスの 1 つで HTC Droid Incredible では wal が有効になっていますが、kindle fire では wal が有効になっていません。

wal が有効になっていないデバイスでは、問題はありません。wal を備えたデバイスでは、実際の db ファイルが最新ではないため、データのインポートとエクスポートが機能していませんでした。変更は wal ファイルに存在し、wal のチェックポイントに到達するまで db ファイルにコミットされません。

インポートおよびエクスポート機能が正しく機能していることを確認するには、データベースに最新の情報が含まれている必要があります。これを達成するには、sqlite ステートメントを実行して、すべての情報を db ファイルにコミットする wal チェックポイントを実行する必要があります。

エクスポートまたはインポート機能を実行する前に、次の sqlite コマンドを実行してチェックポイントを開始し、wal をクリアして、変更をデータベースにコミットします。

PRAGMA wal_checkpoint

チェックポイントが呼び出された後、関数は適切に機能しています

于 2013-01-28T00:34:28.337 に答える