2016-08-04 102 views
2

我想序列化/反序列化一个java枚举为int。我正在使用Android Wear可穿戴数据层API在Wear和Phone设备之间传输枚举设置。这意味着我需要将我的枚举转换为int并以编程方式返回到枚举。请注意,我不需要创建新的枚举,只需匹配现有的枚举。我担心的是,尽管我可以使用枚举方法轻松设置值,但似乎可以轻松设置一个不存在的值。Android枚举:从整数值编程设置枚举

public enum Color { 
    Undefined (0), Red(1), Yellow(2), Blue(3), Green(4), Black(5); 
    private int mValue; 
    private Color(int value) { this.mValue = value;} // Constructor 
    public int id(){return mValue;}     // Return enum index 
    public void setValue(int i){mValue = i;};  // Set index 
} 

因此,我可以做到以下几点:

Color color = Color.Red; 
int index = color.id(); 
putDataMapReq.getDataMap().putInt("color",index);   

此值可运为int,我想如下重建它,但我不能得到的setValue()方法可访问:

int newindex = dataMap.getInt ("color"); 
Color newColor = Color.Undefined; 
newColor.setValue(newIndex); 

这是正确的方法来做到这一点?有没有办法验证新的索引值是否合法?

回答

3

为简单起见,我建议您使用emen的方法namevalueof

Color会是这样:

public enum Color { 
    Undefined , Red, Yellow, Blue, Green, Black; 
} 

序列化:

Color color = Color.Red; 
String name = color.name(); 

反序列化:

String newName = dataMap.getString("color"); 
Color newColor = Color.valueOf(newName); 

UPDATE

如果你想使用整数,你的代码就会像下面:

public enum Color { 
    Undefined (0), Red(1), Yellow(2), Blue(3), Green(4), Black(5); 
    private int mValue; 
    Color(int value) { this.mValue = value;} // Constructor 
    public int id(){return mValue;}     // Return enum index 

    public static Color fromId(int value) { 
     for(Color color : values()) { 
      if (color.mValue == value) { 
       return color; 
      } 
     } 
     return Undefined; 
    } 
} 

序列化:

Color color = Color.Red; 
    int index = color.id(); 

反序列化:

int newIndex = dataMap.getInt("color"); 
    Color newColor = Color.fromId(newIndex); 
+0

是否有可能使用一个整数作为中间值,而不是String。我想尽量减少字符的运输。 – Hephaestus

+0

好的,我更新了我的答案。 – nshmura

+0

甜美!!!!!这正是我想到的。 – Hephaestus

1

首先,我强烈建议您枚举不可变,以防止令用户惊讶。如Java 1.5 documentation中所述的枚举的最初用法是替换常量列表。

至于传输数据时,Android穿戴docs on data syncing建议使用一个DataMap尽可能:

当可能时,使用数据图类。这种方法允许您以Android Bundle的形式处理数据项,因此系统会为您提供对象序列化和反序列化的功能,并且您可以使用键值对操作数据。

虽然我没有与穿戴式设备的经验,Android已经有BundleParcelable自己的序列化机制,并有像Parceler项目,这将有助于为您生成序列化代码。您可以使用#fromBundle(...)将捆绑转换为DataMap。

如果您使用Parceler路由,您可以依赖内置的枚举序列化或编写任意代码。这是一个常见的Java模式通过available values寻找匹配(或在预先计算的地图,如果非常大的期待起来)来创建一些典型值enum实例:

public enum Foo { 
    VAL_1("bar"); 
    private final String strval; 
    Foo(final String strval) { this.strval = strval; } 

    public static Foo fromStrval(final String strval) { 
    for (final Foo f : Foo.values()) { 
     if (f.strval.equals(strval)) return f; 
    } 

    return null; 
    } 
} 
+0

Del。感谢您的评论。我正在使用DataMap API,并且已更新原始帖子以包含实际的数据映射代码。我也检查过,DataMap包不接受枚举(我之前假设过,但现在只是检查)。这是使用int的原因。 – Hephaestus