实施保存设置

时间:2013-04-02 12:58:47

标签: java android serialization save

我正在写一些关于android的游戏。我想知道如何保存设置,以免出现更新问题。 例如,我使用序列化保存设置,我有类GameChar

public class GameChar implements Serializable{

  int health;
  int damage;

  Sword sword;
}

但后来我决定为我的游戏角色增加值装甲,我改变了类:

public class GameChar implements Serializable{

  int health;
  int damage;

  int armor;

  Sword sword;
}

现在有了更新,我放松了所有进度,因为新课程GameCharGameChar不同。 我有一个想法是使用Map<String, Object>其中key是我保存的值的名称,值是我想要的任何ObjectIntegerFloatCalendar或某些我的用户类Sword)。我会将此Map保存到Serialization的文件中。

但是,如果我更改了部分用户类Sword,那么它将与我Map中的用户类不同,并且我将再次通知更新。

也许有一些模式或技术让我更加优雅。

4 个答案:

答案 0 :(得分:2)

您是否注意到,在实施Serializable时,系统会要求您声明名为static long的{​​{1}}?

此变量的目的是在反序列化时检测类的旧版本。尝试使用版本serialVersionUID类从保存的数据反序列化版本1对象将导致异常。

(您可以自己实现此行为,如果您不使用Java的序列化工具,它只是一个数字和2

一旦检测到您保存的对象是陈旧的,并且与当前的类定义不匹配,您可以手动修复该问题。例如,如果您知道在版本if中声明了新成员int a;,并且您选择了使用版本2序列化的对象,则可以指定一个有意义的值,尽管它是保存的信息中缺少。

不幸的是,跟踪版本是你的工作。最简单的方法是确保始终可以从较旧版本实例化新版本而不进行任何调整 - 例如,1是有意义的值。

答案 1 :(得分:0)

我估计你应该看看SharedPreferences(这是一种地图) http://developer.android.com/guide/topics/data/data-storage.html#pref

从您的示例类我将使用它而不是序列化该类,只需手动将每个项目保存到SharedPreferences中,并且永远不会出现任何序列化问题。

答案 2 :(得分:0)

实际上,您将在反序列化时检查对象的版本并将其替换为更新版本。 Check this link out

答案 3 :(得分:0)

“技巧”是覆盖readObject方法并捕获在序列化的以前版本的GameChar中读取时发生的EOFException。在exeption处理程序中,您可以为armor分配一个默认值。由于这需要声明变量瞬态,因此还需要覆盖writeObject方法。此示例不包含Sword,如果存在不同版本的Sword(相同过程),则Sword本身应覆盖readObject和writeObject方法。如果版本超过2个,则应使用变量“version”并根据该变量的值读取对象。

public class GameChar implements Serializable {

private static final long serialVersionUID = 12345L; // use serialver to determine UID
transient private int health;
transient private int damage;
transient private int armor;

private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws IOException {
    s.writeInt(health);
    s.writeInt(damage);
    s.writeInt(armor);

}

private synchronized void readObject(java.io.ObjectInputStream s)
        throws IOException, ClassNotFoundException {
    health = s.readInt();
    damage = s.readInt();
    try {
        armor = s.readInt();
    } catch (EOFException eofex) {
        armor = 999; // default value
    }
}
}

如果使用这样的“version”变量,readObject方法可能如下所示:

private synchronized void readObject(java.io.ObjectInputStream s)
        throws IOException {
    version = s.readInt();
    health = s.readInt();
    damage = s.readInt();
    switch(version) {
        case 1: armor = 999; // default;
            break;
        case 2: armor = s.readInt();
    }
}