我的备份弄丢了所有照片

我为一款离线情绪追踪应用开发了一个备份按钮。

它将数据导出为 JSON 文件。用户可以保存该文件并将其迁移到新手机上。这看起来很完美。

然后我更改了应用的包名(package ID)。我在一台新设备上尝试重新安装并恢复了备份。

文本条目都回来了。所有的照片都消失了。

我意识到了我的错误。这个备份并不是真正的备份。它仅仅是一系列指向已不存在文件的指针列表。

应用将照片存储在磁盘上,而数据库中仅保存了文件路径。

路径看起来像这样: file:///data/user/0/com.example.app/files/entry_media/image.jpg

当我导出 JSON 时,我只保存了那个路径。在同一台设备上,导入功能可以正常工作,因为文件仍然存在。

在新设备上,这些路径指向的是空地址。用户会看到破碎的缩略图,并认为应用删除了他们的记忆。

如果你的导出文件只包含文件路径,那么你拥有的并不是一个可移植的备份。你拥有的只是一个仅在不需要备份的机器上才有效的备份。

真正的备份必须包含实际的数据。

我更改了流程。现在,导出过程会读取每张照片,并将其转换为 JSON 内部的 Base64 字符串。

这种方法也有权衡之处: • 文件体积会增加约 33%。 • 在导出大型库时需要消耗更多内存。

我选择了正确性而非文件大小。一个庞大的备份是有用的,而一个丢失了所有图片的微小备份则毫无价值。

我还更改了导入的处理方式,以确保速度和安全性:

  1. 首先将所有照片写入新设备的磁盘。这一步在数据库事务之外进行,以保持速度。
  2. 运行单个数据库事务,将新的本地路径与条目关联起来。

我还构建了系统的容错机制(fail soft)。如果某张照片缺失或无法读取,应用会跳过它并继续处理下一张。一张损坏的图片不应该导致整个恢复过程崩溃。

教训:

  • 以正确的方式进行测试。在一台设备上导出,擦除数据,然后在全新安装的应用上导入。在同一台设备上重复导入会掩盖 Bug。
  • 携带字节数据。如果数据必须在更换设备后依然存在,请移动实际的数据,而不是地址。

来源:https://dev.to/diven_rastdus_c5af27d68f3/my-offline-apps-backup-lost-every-photo-on-a-new-phone-3d36