2012-05-01 171 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是迄今为止我见过的其他建议中最好的,并且承诺在棉花糖方面有一个更好的方法来处理这个问题。