我想知道在Android上备份和恢复SQLite数据库的最佳做法是什么。目前我通过备份数据库并使用文件输入/输出流将其复制到SD卡来解决问题。然后,如果我想恢复和旧备份,我使用反向过程。
此方法似乎有效并且尚未损坏我的数据。我想知道这是最好的方法还是有更安全的方法呢?
由于
答案 0 :(得分:17)
仅支持数据库的FYI。我目前在我的应用程序中执行此操作的方式与您上面解释的相同。以这种方式创建备份时要小心。它在大多数情况下都很有用,但问题是所创建的备份不能保证与所有设备和Android版本兼容。我第一次听到这个声音时觉得这听起来很奇怪,但我现在发现这是真的。我最近收到了一些关于丢失数据,数据消失等的报告。当用户从其他设备或不同的Android版本或ROM恢复备份时,就会发生这种情况。他们中的一些人直接与我联系,这很棒,所以我能够从中获取备份文件以测试它们并检查它们。当我尝试恢复它们时,我会收到以下logcat错误: android.database.sqlite.sqlitedatabasecorruptexception:数据库磁盘映像格式错误
我发现的是,主要是某些HTC设备和一些自定义ROM(在任何设备上)创建的这些备份无法恢复到其他设备或ROM。数据库并没有真正腐败,但Android认为它们是。我会将它们带入SQLite浏览器,也没有数据显示。事实证明,较新版本的SQLite默认启用了WAL(写入前端日志记录),如果它已启用并且使用该数据库进行备份,则无法将其还原到旧版本的SQLite,甚至有时也无法恢复到相同版本(对于一些奇怪的原因)。因此,我使用“PRAGMA journal_mode = DELETE”禁用WAL,然后我能够在浏览器中查看数据库并能够在我的测试设备上恢复它。另一个问题是,似乎没有办法在代码中捕获此异常,Android会在遇到此异常时自动删除数据库(在我看来Android上的管理非常糟糕)。
很抱歉我的回复很长,但我想通过这种备份来解释我所看到的情况。我正在尝试寻找另一种在SD卡上创建通用备份的方法。创建像@Kingamajick这样的csv文件和sql脚本可能是另一种方法。这是更多的代码和更多的工作,但如果它适用于任何设备,SQLite版本和ROM,那么它是值得的。您的客户丢失数据永远不是一件好事。
答案 1 :(得分:4)
这似乎是最好的方法。在复制之前,您可能需要考虑对SQLite文件进行校验和,并将其与目标文件进行比较以获得额外的保证。只需确保在复制时没有与数据库的打开连接,否则在恢复时可能会导致数据库处于意外状态。
我能看到的另一种方法是读取数据库的实际内容并生成一个包含SQL的文件,它可以从中恢复,这显然更复杂,不提供任何有利于证明这种复杂性的好处。
答案 2 :(得分:0)
我会在Kingamajick的回答中添加一条评论(论坛不会让我将其添加为实际评论)。在简单地复制文件的方法中,如果用户曾经恢复数据库并且其中已经存在任何数据,则它将被覆盖。例如,如果用户升级到新手机,使用它一段时间,然后从旧手机恢复数据库,则新手机上已有的任何数据都将丢失。这是读取数据库并将其写入文件(XML或CSV等)的复杂性的一个优点。
我发布了另一个问题(Android sqlite backup/restore without overwriting)希望有人有一个更好的解决方案来避免这个问题,但到目前为止似乎没有一个问题。在那之间和问题ssuperz28指出,备份你的数据库似乎是一种更安全的方法是将其写入xml然后读取它并在恢复时将其重新添加。
此外,https://stackoverflow.com/a/34477622/3108762是迄今为止我见过的其他建议中最好的,并承诺从Marshmallow开始更好地解决这个问题。