Android枚举:以编程方式从整数值设置枚举

Posted

技术标签:

【中文标题】Android枚举:以编程方式从整数值设置枚举【英文标题】:Android enum: set enum programatically from integer value 【发布时间】:2016-12-10 00:55:30 【问题描述】:

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

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);

这样做的正确方法是什么?有没有办法验证新的索引值是否合法?

【问题讨论】:

【参考方案1】:

为了简单起见,我推荐你使用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);

更新

如果你想使用整数,你的代码如下:

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);

【讨论】:

是否可以使用整数作为中间值,而不是字符串。我想最小化传输字符。【参考方案2】:

首先,我强烈建议您将枚举设为不可变,以防止其用户感到惊讶。 Java 1.5 documentation 中所述的枚举的原始用途是替换常量列表。

关于传输数据,Android Wearable docs on data syncing 建议尽可能使用DataMap:

如果可能,请使用 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;
  

【讨论】:

德尔。谢谢你的cmets。我正在使用 DataMap API,并且我已经更新了原始帖子以包含实际的数据映射代码。我还检查了 DataMap 包不接受枚举(我之前假设过,但现在才检查过)。这就是使用 int 的原因。

以上是关于Android枚举:以编程方式从整数值设置枚举的主要内容,如果未能解决你的问题,请参考以下文章

Enum枚举

以编程方式枚举发布页面布局的 Web 部件区域

Swift:以编程方式枚举来自 UIVIewController 的传出 segue

Swift函数式编程七(枚举)

Swift函数式编程七(枚举)

如何使用 MDbg 以编程方式枚举正在运行的 .NET 进程中的类型?