2012-05-01 167 views
2

我想知道什麼是在Android上備份和恢復SQLite數據庫的最佳做法。目前我通過將DB備份並使用文件輸入/輸出流將其複製到SD卡來解決問題。然後我使用相反的過程,如果我想恢復和舊的備份。Sqlite DB Android備份/恢復

此方法似乎工作,並且尚未破壞我的數據。我想知道這是最好的方法,還是有更安全的方法?

謝謝

回答

4

這看起來好像是最好的方法。您可能需要考慮在複製之前獲取SQLite文件的校驗和,並將其與目標文件進行比較以獲得額外保證。只需確保在複製副本時沒有與數據庫建立任何開放連接,否則當數據庫恢復時,數據庫可能處於意外狀態。

我可以看到做的唯一另一種方式是讀取數據庫的實際內容並生成一個包含可從中恢復的SQL的文件,這顯然更復雜,並且不會提供任何優勢來證明這種複雜性。

16

只是備份數據庫的一個參考。我目前在我的應用中以與上面解釋相同的方式執行此操作。謹防以這種方式創建備份。它在大多數情況下效果很好,但問題是創建的備份不能保證與所有設備和Android版本兼容。我第一次聽到這個時聽起來很奇怪,但我現在發現它是真的。最近我收到了幾份關於數據丟失,數據丟失等報告。當用戶從不同的設備或不同的Android版本或ROM恢復備份時,都會發生這種情況。他們中的一些人直接與我聯繫,這非常棒,所以我可以從備份文件中進行測試並對其進行檢查。當我試圖恢復他們,我會得到下面的logcat錯誤:android.database.sqlite.sqlitedatabasecorruptexception:數據庫磁盤映像格式不正確

什麼,我查不到是,主要是,某些HTC設備和一些定製ROM(在任何設備上)創建的這些備份不會恢復到其他設備或ROM。數據庫並沒有真正的腐敗,但Android認爲它們是。我會帶他們進入一個SQLite瀏覽器,沒有數據會顯示在那裏。事實證明,較新版本的SQLite默認情況下啓用了WAL(預寫日誌記錄),並且如果它啓用並且使用該數據庫進行了備份,則無法將其恢復到較舊版本的SQLite甚至有時也是相同版本(用於一些奇怪的原因)。所以,我用「PRAGMA journal_mode = DELETE」禁用了WAL,然後我能夠在瀏覽器中查看數據庫,並且能夠在我的測試設備上正常恢復它。另一個問題是,似乎沒有辦法在代碼中捕獲這種異常,Android在遇到此異常時會自動刪除數據庫(我認爲Android的管理非常糟糕)。

對不起,我想解釋一下我看到的這種備份。我正在試圖尋找另一種在SD卡上創建通用備份的方法。創建csv文件和sql腳本,如@Kingamajick說可能是另一種方式來做到這一點。這是更多的代碼和更多的工作,但如果它適用於任何設備,SQLite版本和ROM,那麼這將是值得的。您的客戶丟失數據從來就不是好事。

+0

你可以指定你發現哪些API發佈的問題。thx –

+1

運行Android 2.3的HTC設備上已經發生這種情況我也在CM7和CM9 ROM上看到它。這並不是所有的HTC設備,最明顯的是Desire系列。顯然那些HTC設備和Cyanogemod默認在SQLite中啓用了WAL,並且它們不能很好地與其他ROM,設備或SQLite版本兼容。我在考慮更多的設備獲得ICS和更新版本的SQLite,這些在pre 4.0設備上創建的較舊備份在恢復時將開始出現問題。直到2.3.3+發佈以及更多設備從FROYO移開後,我纔看到這樣的例外。 – ssuperz28

+0

您是否使用Sqlite中的事務來確保數據全部或全部未寫入? –

0

我想爲Kingamajick的回答添加一個額外的評論(論壇不會讓我把它作爲一個實際的評論添加進去)。在簡單複製文件的方法中,如果用戶曾經恢復數據庫,並且恰好有已經存在的數據,它將被覆蓋。例如,如果用戶升級到新手機,使用它一段時間,然後從舊手機恢復數據庫,新手機上已有的數據將會丟失。這是讀取數據庫並將其寫入文件(XML或CSV等)的複雜性的一個優點。

我發佈了另一個問題(Android sqlite backup/restore without overwriting),希望有人有一個更好的解決方案,以避免這個問題,但到目前爲止似乎沒有一個。在這之間和擔心ssuperz28指出,備份數據庫似乎是一種更安全的方法是將其寫入xml,然後讀取它並將其添加回恢復。

另外,https://stackoverflow.com/a/34477622/3108762是迄今爲止我見過的其他建議中最好的,並且承諾在棉花糖方面有一個更好的方法來處理這個問題。