2012-05-01 39 views
2

アンドロイドでSQLite DBをバックアップして復元するためのベストプラクティスを知りたかったのです。現在私は、DBをバックアップし、File Input/Output Streamsを使用してSDカードにコピーすることで、この問題に取り組んでいます。その後、元のバックアップを復元する場合は、逆のプロセスを使用します。Sqlite DB Androidバックアップ/リストア

この方法は機能しているようで、まだデータが破損していません。私はこれが最善のアプローチか、これを行うより安全な方法があるかどうか疑問に思いますか?

ありがとうございました

答えて

4

これは最善のアプローチのようです。 SQLiteファイルのチェックサムをコピーし、それを目的のファイルと比較して余分な保証を得ることを検討することをお勧めします。コピーを取ったときにデータベースへの接続が開いていないことを確認してください。そうしないと、DBが復元時に予期しない状態になる可能性があります。

私が見ることができる唯一の方法は、DBの実際の内容を読んで、それを元に戻すことができるSQLを含むファイルを生成することです。これは明らかに複雑であり、この複雑さを正当化するための利点を提供します。

16

データベースをバックアップする際の参考になります。私は現在、あなたが上で説明しているのと同じ方法で私のアプリでこれを行います。この方法でバックアップを作成するときは注意してください。これは大部分の場合はうまくいくが、問題は、作成されたバックアップがすべてのデバイスとAndroidバージョンとの互換性が保証されていないことである。私はこれを初めて聞いたときにこれが奇妙に聞こえたと思っていましたが、私は今それが真実であることを発見しています。私は最近、データの欠落、データの消失などのいくつかの報告を受けています。これは、ユーザーが別のデバイスまたは異なるAndroidバージョンまたはROMからバックアップをリストアしていたときに起こっていました。彼らのうちのいくつかが私に直接連絡してくれました。それは素晴らしかったので、バックアップファイルをテストして調べることができました。私はそれらを復元しようとしたとき、私は次のlogcatエラーになるだろう:android.database.sqlite.sqlitedatabasecorruptexception:データベースのディスクイメージが

だった私は何を見つけ出すたことを、主に、特定のHTCデバイスといくつかのカスタム不正な形式でありますROMは他のデバイスやROMに復元しないバックアップを作成していました。データベースは本当に壊れていませんでしたが、アンドロイドはそれがだと思いました。私はそれらをSQLiteブラウザに取り込み、データもそこには表示されません。新しいバージョンのSQLiteでは、デフォルトでWAL(Write Ahead Logging)が有効になっており、有効にされ、そのデータベースでバックアップが作成されていれば、古いバージョンのSQLiteに復元することはできません。いくつかの奇妙な理由)。そこで、私は "PRAGMA journal_mode = DELETE"でWALを無効にして、ブラウザでデータベースを表示でき、テストデバイスで正常にリストアできました。もう1つの問題は、コード内でこの例外をキャッチする方法がないように見えることと、この例外を跨いだときにAndroidが自動的にデータベースを削除することです(私の意見ではAndroidの管理上の非常に悪い管理です)。

長い応答で申し訳ありませんが、私はこの種のバックアップで何が起こっているのかを説明したかったのです。 SDカードにユニバーサルバックアップを作成する別の方法を見つけようとしています。 @ Kingamajickのようなcsvファイルとsqlスクリプトを作成することは、別の方法かもしれません。それはより多くのコードとより多くの仕事ですが、それがどんなデバイスでも動作するなら、SQLiteのバージョンとROMなら価値があります。あなたの顧客がデータを失うことは決して良いことではありません。

+0

問題が見つかったAPIリリースを指定できますか。 –

+1

これはAndroid 2.3を実行しているHTCデバイスで発生しています。CM7とCM9のROMでも見ました。それはすべてのHTCデバイス、特にDesireシリーズではない。どうやらこれらのHTCデバイスとCyanogemodはデフォルトでSQLiteでWALを有効にしており、他のROM、デバイス、またはSQLiteバージョンではうまく動作しません。より多くのデバイスがICSと新しいバージョンのSQLiteを入手するにつれて、4.0より前のデバイスで作成されたこれらの古いバックアップは、リストア時に問題が発生し始めると考えています。 2.3.3以降がリリースされ、より多くのデバイスがFROYOから離れるまで、このような例外は見られませんでした。 – ssuperz28

+0

あなたはSqliteでトランザクションを使用して、データがすべて書かれているかどうかを確認していますか? –

0

私はKingamajickの答えに1つのコメントを追加したいと思います(フォーラムで実際にコメントとして追加することはできません)。単純にファイルをコピーするアプローチでは、ユーザーがDBをリストアした後にすでにデータが存在する場合、そのデータは上書きされます。たとえば、あるユーザが新しい電話機にアップグレードしてしばらく使用した後、古い電話機からDBを復元すると、新しい電話機にすでにあるデータは失われます。これは、DBを読み込んでファイル(XMLまたはCSVなど)に書き出す複雑さの1つの利点です。

誰かがこの問題を回避するより良い解決策を望んでいたとして別の質問(Android sqlite backup/restore without overwriting)を投稿しましたが、今のところはそうではないようです。 ssuperz28との間には、あなたのDBをバックアップする方がはるかに安全な方法のように思えますが、xmlに書き出してから読み込み、復元時にそれを追加してください。

また、https://stackoverflow.com/a/34477622/3108762はこれまでに見た他の提案の中でも最高のものであり、マーシュマローを起点にこれにアプローチするより良い方法を約束します。