在android上保存文件时避免因中断而导致的数据丢失?

时间:2012-04-20 13:22:14

标签: android xml file

我想知道其他人在Android上保存文件时使用什么策略来避免数据丢失。我有几个游戏应用程序,基本上,只要用户暂停(onPause),它们就可以保存游戏状态/存档游戏。

这在99.99%的情况下有效,但每隔一段时间我就会收到一个存档过程出错的存档游戏示例。通常,这是一个格式错误的XML文件,通常在某个任意点被截断。基于我收到的错误报告,我认为问题主要发生在用户在游戏过程中通过电话或其他类似情况中断时,Android操作系统会在应用程序完成保存之前杀死应用程序。保存文件的代码非常简单,因此我很难看到其他可能导致此问题的原因。

这是一个严重的问题,因为它通常会导致玩家的保存进度被破坏。

我想先写一个空文件,然后再复制到“真实”文件,但我怀疑这只会增加问题,因为它总会花费更多时间,但仍有被打断的风险。

任何有安全管理方法的人都相对保证Android不会搞砸?


如此总结,到目前为止建议的选项(据我所知):

  1. 使用服务进行保存,假设操作系统不太可能将其杀死。
  2. 保存在临时文件中;保存验证后复制。
  3. 增量保存游戏状态(我实际上已将此用于播放器日志信息)。
  4. 2&组合3。
  5. 将保存移至另一个主题,因为问题可能是ANR导致[DC的评论如下]。
  6. 我不认为SharedPreferences会对这种结构化数据起作用。目前,这些方法似乎都不是理想的解决方案,所以我仍然愿意接受建议。


    我还没有设法测试所有这些方法,所以我没有浪费赏金,而是将其分配给我认为最有可能解决问题的答案。不过,我计划在接受答案之前检查各种选项。感谢所有好的建议。

5 个答案:

答案 0 :(得分:4)

答案 1 :(得分:3)

当我们从主线程进行持久存储(内部存储器上的私有文件系统)的I / O(通常是写入)时,我们偶尔会遇到问题。通常这不需要花费太多时间,但偶尔会花费很长时间(20或30秒或更长)。似乎某些设备上的Android文件系统实现不支持并发访问(请参阅this,因此如果另一个进程正在使用文件系统,则I / O可能会阻塞。如果您在主服务器上执行I / O操作如果线程阻塞太久,操作系统可以/将会杀死你的活动。这可能是你发生的事情。

由于这个问题,我建议您将所有I / O移动到一个单独的线程(而不是主线程)。因此,例如,为了保存游戏状态,在onPause()中调用一个方法,将游戏状态序列化为ByteArrayOutputStream,然后将其移交给一个单独的线程,最终写入文件系统。

答案 2 :(得分:2)

我认为每次用户执行任何操作(不仅在调用onPause()时)都会将数据的一小部分(不是整个游戏状态)保存到数据库中,这将是这种情况下的最佳方法。但是,这可能需要对代码进行大量修改。

妥协方案是将游戏状态分成较小的部分或子状态(比方说, round1 round2 ,. .., players 等)并在用户执行任何操作时再次将数据存储到适当的文件,而不是等待onPause()调用。这将显着降低丢失的可能性,并且至少可以保证用户不会失去整个游戏进度。此外,为了避免在保存过程中断时可能出现的应用程序状态不一致,您最好先将数据保存到临时文件中,只有在成功的情况下才重命名文件,而不是复制其内容(比方说,< em> round1.xml.tmp 重命名为 round1.xml )。

答案 3 :(得分:0)

如果可能,请使用SharedPreferences来存储您的游戏状态。只有在致电commit()后,您的更改才会提交。您可以在onSaveInstanceState回调中进行保存。阅读docs here.

答案 4 :(得分:0)

首先,我会试着看看应用程序是否真的被杀死而没有通知,因为我不认为应该是这种情况。应用程序可能会因为电话等问题而被停止,但我并不认为安卓只是在没有任何通知的情况下杀死它。它可以决定结束它,但不能没有保存状态等。

可能保存本身只会出现错误。

一种不需要太多修改的方法来检查是使用校验和还是使用其他方法来验证保存数据的完整性(大小,结束标记等)。您所要做的就是保存,阅读并检查(记录任何错误)并重复该操作直至其正确。如果您保存大量数据可能不是那么好,但仅仅是游戏数据它应该没问题。

您还可以在应用程序开始和结束时设置状态,然后在下次启动时知道最后一次是否正确结束以及是否需要采取额外措施。