本文译自:http://developer.android.com/training/cloudsave/conflict-res.html
本文介绍如何使用云存储服务为应用程序的数据存储设计强壮的冲突解决策略。该云存储服务允许你把应用程序的每个用户的应用数据保存到Google的服务器上。通过使用云存储API,你的应用程序能够获取和更新来自Android设备、iOS设备、或Web应用的用户数据。
把数据保存到云存储中,以及从其中装载数据的处理是简单的:它只是一个字节数组的系列化和反系列化的处理。但是当用户有多个设备,有两个以上的设备试图把数据保存到云端,这时存储就可能发生冲突,因此你必须决定如何来解决它。你的云端存储数据的结构在很大程度上决定了解决这种冲突的能力,因此必须认真的设计你的数据,以便允许解决冲突的逻辑能够正确的处理每种情况。
本文介绍了几种有缺陷的方法,并解释了它们的不足之处,然后提出了一个避免冲突的解决方案,该方案讨论的重点在游戏,但这些把数据保存到云端的原则可以应用到任何应用程序。
获取冲突通知
OnStateLoadedListener方法负责从Google的 服务中加载应用程序的状态数据。OnStateLoadedListener.onStateConflict方法为应用程序在用户设备上的本地状态与云端的状态之间提供了一种解决冲突的机制:
@Override
public void onStateConflict(int stateKey, String resolvedVersion,
byte[] localData, byte[] serverData) {
// resolve conflict, thencall mAppStateClient.resolveConflict()
...
}
此时,你的应用程序必须选择一个要保持的数据集,也可以提交一个新的被合并的数据集。这种解决冲突的逻辑需要你自己来实现。
要认识到的重要一点时,云存储服务是在后台同步数据的。因此要确保你的应用程序能够接收初始产生数据的上下文之外的回调。特别是如果Google Play服务程序在后台检测到一个冲突,那么该回调会在下次试图加载数据时被调用,这样就有可能直到下次用户启动应用程序时调用才会发生。
因此,云存储数据的设计和冲突解决的代码必须是上下文无关的:给定两个冲突数据的保存状态,必须能够只使用数据集内部的有效数据就能够解决冲突,而不用关心任何外部环境。
处理简单的情况
以下是一些简单的冲突解决方法,对已大多数应用程序来说,使用下列策略之一就足以解决问题:
1. 新数据要优于旧数据:在某些场景中,新数据应该始终要替换旧数据。例如,如果数据代表了游戏者所选择的衬衫的颜色,那么最近一次的选择应该覆盖以前的选择。在这种情况中,你可能需要选择在云存储的数据中保存时间戳。这样在解决冲突时,选取最近一次的时间戳的数据就可以了(记住要使用可靠的时钟,并要注意时区的差异)。
2. 一组数据集要优于其他数据:在有些场景中,总是要关注那些被定义为“最好”的数据。例如,如果数据代表了游戏者在竞赛游戏中表现最佳的时间,那么在这种情况下,如果发生冲突,你就应该保持那个成绩最好的时间。
3. 合并数据:通过计算两个冲突的数据集的合集来解决冲突问题也是可能的。例如,如果你的数据代表了一组已经被游戏者解锁的游戏等级,那么解决的办法就是简单的把两个冲突的数据集合并到一起就可以了。这种方法,游戏者不会丢失任何已经被解锁的游戏等级。