【发布时间】:2012-05-02 02:11:50
【问题描述】:
我想知道其他人在 Android 上保存文件时使用什么策略来避免数据丢失。我有几个游戏应用程序,基本上,它们可能会在用户暂停时保存游戏状态/保存游戏(onPause)。
这在 99.99% 的情况下都有效,但每隔一段时间我都会收到一个保存过程出错的存档游戏示例。通常,这是一个格式错误的 XML 文件,通常在某个任意点被截断。根据我收到的错误报告,我认为问题主要发生在用户在游戏过程中被电话或类似的东西打断,然后 Android 操作系统在应用程序完成保存之前将其杀死。保存文件的代码非常简单,所以我很难看出还有什么可能导致这个问题。
这是一个严重的问题,因为它通常会导致玩家的保存进度被破坏。
我想先写入一个空文件,然后再复制到“真实”文件,但我怀疑这只会增加问题,因为它总体上需要更多时间并且仍然有被中断的风险。
谁有安全的方式来做到这一点,Android 相对保证不会搞砸?
如此总结,目前建议的选项(据我了解):
- 为保存过程使用服务,假设这不太可能被操作系统杀死。
- 保存在临时文件中;验证保存后复制。
- 游戏状态的增量保存(我实际上已经将它用于玩家日志信息)。
- 2 和 3 的组合。
- 将保存移至另一个线程,因为问题可能出在 ANR 杀死 [DC 的 cmets 下面]。
我认为 SharedPreferences 不适用于这种结构化数据,目前,这两种方法似乎都不是理想的解决方案,所以我仍然愿意接受建议。
我还没有设法测试所有这些方法,因此我没有浪费赏金,而是将其分配给我认为最有可能解决问题的答案。不过,在接受答案之前,我仍计划检查各种选项。感谢所有好的建议。
【问题讨论】:
-
保存到
SharedPreference的数据是不是太多了? -
是的 - 大约 20K 的 XML 数据。这可能不是一个主要问题(没有尝试过),但我认为数据结构相当复杂。
-
你是如何在
onPause()中保存游戏状态的?您是否在主 (UI) 线程上执行 I/O?您将游戏状态保存在哪里(在 SD 卡或其他位置)? -
是的,它通常在 onPause 上完成,并且直接从函数(主线程)中完成。从来没有费心将它移动到线程中,因为保存时间从来都不是问题(据我所知),除了(大概)这个问题。
-
我要补充:5。将保存移动到另一个线程。 到您的列表。你说它的发生率为 0.01%,这让我相信这是某些 Android 设备不支持并发文件系统访问的问题。如果您在任何应用程序上阻塞 UI 线程,Android 将在几秒钟后将其终止。如果你线程它,Android将没有理由杀死它,因为UI线程没有被阻塞。现在,如果可能,您应该/可能等待
onFinish()中的线程。但是在杀死应用的情况下,Android 甚至不保证会调用onFinish()。