应用程序意外退出时防止数据损坏

Posted

技术标签:

【中文标题】应用程序意外退出时防止数据损坏【英文标题】:Preventing data corruption when app exits unexpectedly 【发布时间】:2016-09-04 20:29:56 【问题描述】:

我目前正在为 android 设备开发一款 RPG 游戏,并且刚刚实现了一种用于保存玩家进度的自定义序列化方法。保存过程可能需要半秒时间,这足以发生崩溃(由设备(即电池电量不足)、用户(杀死应用程序)或编写不当的固件/ROM(内核崩溃)引起) ) 等)。

在保存玩家数据时,旧的玩家数据会被覆盖。这意味着如果发生崩溃,并且如果保存过程因此被取消/中断,则玩家的数据将会丢失。这显然是不理想的,在未来,游戏将保存更多的数据,保存时间会更长。这将增加在保存过程中发生崩溃的可能性。

我无法减少保存时间,因为我正在编写游戏重新启动后能够恢复游戏所需的最少数据。

我可以采取哪些万无一失的措施(如果有)来防止此类数据损坏/丢失的发生?

【问题讨论】:

为什么不保存在一组临时文件中并在该过程完成后移动/重命名它们,然后删除以前的保存文件? @SR_ 感谢您的回答。这似乎是个好主意,也是我真正拥有的唯一选择。我可能会实现这样的东西。 【参考方案1】:

您可以将数据保存在一组临时文件中,并在该过程完成后移动/重命名它们,然后删除以前的保存文件。

如果您对重命名过程没有信心,可以添加以下约束:

    确保数据与校验和一致 始终尝试从上次一致保存的状态恢复,具体取决于您自己的规则(文件名,...)

另一个想法是将您的数据切成小块,以隔离不改变的状态。 如果保存时间真的很长,你可以尝试在游戏过程中使用剩余的 CPU 时间来预先保存当前状态中可能不会改变的部分(例如使用较低优先级的线程)。

【讨论】:

感谢您的回答。我可能会实现这样的东西,因为它比使用 SQLite 数据库更容易。【参考方案2】:

您可以将数据保存到SQLiteDatabase。如果更改保存数据失败或中断,数据库将自动回滚到之前的已知状态。

如果您需要以原子方式执行多个更新,为了提高安全性,请将您的所有更改放入一个事务中。如果任何更改失败,则整个事务将回滚到事务前状态。

有关使用 SQLite 的更多信息,请参阅文档 here。为了在您想与其他应用共享或将其同步到备份服务器时更轻松地操作您的保存数据,请考虑通过ContentProvider 与您的数据进行交互。

【讨论】:

感谢您的回答。虽然这是一个好主意,而且我喜欢它回滚的事实,但我认为 SQLite 数据库不适合游戏,因为我真的不想为每条单独的信息创建表和字段想要存储。 了解您不想使用数据库。但是,如果游戏需要存储和检索结构化数据,我认为数据库适合游戏。数据库的难点在于预先决定存储数据的最佳方式,但我发现设计良好的数据库在易用性和可靠性方面很难被击败。 我同意你的观点,但我很懒,我宁愿不改变我刚刚写的序列化系统:P 到一些需要我几个小时的东西(我是一个单人开发-团队...)

以上是关于应用程序意外退出时防止数据损坏的主要内容,如果未能解决你的问题,请参考以下文章

当线程在保存时被杀死时,如何防止 NSManagedObjectContext 损坏数据库?

当我调用 setAdapter() 到 recycleView 时,我的 Android 应用程序意外退出

SQLite3的数据库文件在突然断电或操作系统崩溃时会损坏吗?

数据备份恢复软件,防止勒索病毒

fontComboBox QSettings 应用程序意外退出

当我关闭蓝牙服务器套接字或蓝牙套接字时,Android 应用程序意外退出