2010-07-20 33 views
224

如何将Enum对象添加到Android Bundle?Android:如何把一个枚举放在一个包中?

+8

在我看来,从谷歌的工作人员的建议是不好的。枚举是非常方便的,并且所描述的开销会受到影响。 – ognian 2010-07-20 18:24:29

+2

如果您认为这可能是一个更好的选择,您是否可以重新回答答案并接受第二个答案。 – philipp 2012-09-06 19:43:05

+5

在上面的链接中,标题为“避免使用枚举”现在这样说:性能神话 本文档的先前版本提出了各种误导性声明。我们在这里解决其中一些问题。 – StackOverflowed 2012-10-02 11:00:25

回答

-21

只需将它作为int从ordinal()中传递即可。从值[]中恢复。

+75

这是不推荐的。问题是可维护性问题之一。 Intent可能来自其他来源,或者来源于读取比从Bundle恢复枚举的代码版本更早的数据的代码。因此,保存的序号可能不对应于正确的枚举值的索引。建议的解决方案是@miguel所提供的解决方案:直接存储枚举并通过调用Intent#getSerializableExtra(String)来恢复它,并将其恢复为枚举类型。 – Warlax 2012-07-14 18:48:07

+1

老旧不好看看http:// stackoverflow。com/a/5309967/261363 – Calin 2013-07-05 15:55:23

+1

请标记@ miguel的答案是正确的。谢谢。 – 2017-04-17 15:21:57

15

从myEnumValue.name()中将它作为字符串传递并从YourEnums.valueOf(s)中恢复它可能会更好,否则必须保留枚举的排序!

更详细的解释:Convert from enum ordinal to enum type

+0

如果序列化 - >反序列化在运行时立即发生,例如从一个活动调用到另一个时,顺序无关紧要。这可能是一个问题,例如从一个应用程序发送内容到旧版本的应用程序。 – miguel 2016-06-09 05:27:00

513

枚举是序列化的,所以没有问题。

鉴于以下枚举:

enum YourEnum { 
    TYPE1, 
    TYPE2 
} 

软件包:

// put 
bundle.putSerializable("key", YourEnum.TYPE1); 

// get 
YourEnum yourenum = (YourEnum) bundle.get("key"); 

意图:

// put 
intent.putExtra("key", yourEnum); 

// get 
yourEnum = (YourEnum) intent.getSerializableExtra("key"); 
+0

这个方法有什么问题: save:'outState.putSerializable(“trollData”,game.getFunkyTrolls());'loading:'game.setFunkyTrolls((Game.FunkyTroll [])savedInstanceState.getSerializable(“trollData” ));'? – Moberg 2013-05-22 12:03:18

+19

我会投你的答案,但问题是关于将Enum添加到一个Bundle中,并且你的回复解释了如何将它添加到一个Intent中......这几乎是一回事,但下面的Alejandro修复了你的答案。 – Pooks 2013-09-27 05:34:44

+1

与Bundle一起使用时,它会抛出'ClassNotFoundException' – 2014-03-23 20:28:41

145

我知道这是一个老问题,但我带着同样的问题,我想分享我是如何解决它的。关键是米格尔所说的:枚举是可序列化的。

给出下面的枚举:

enum YourEnumType { 
    ENUM_KEY_1, 
    ENUM_KEY_2 
} 

地说:

Bundle args = new Bundle(); 
args.putSerializable("arg", YourEnumType.ENUM_KEY_1); 
+9

这应该是被接受的答案...... – Mars 2014-03-26 09:33:04

+3

基于此:http: //sackoverflow.com/questions/15521309/is-custom-enum-serializable-too,自定义枚举不可序列化。所以Enum中的自定义字段不会被序列化。你如何处理这个问题? – clu 2015-01-08 19:03:26

+0

不错的问题@clu!也许那么你应该认为通过它作为一个字符串,如http://stackoverflow.com/questions/609860/convert-from-enum-ordinal-to-enum-type/609879#609879 – 2015-01-11 02:07:26

32

为了完整起见,这是一个如何把中并取回从包枚举一个完整的例子。

鉴于以下枚举:

enum EnumType{ 
    ENUM_VALUE_1, 
    ENUM_VALUE_2 
} 

你可以把枚举成一束:

bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1); 

,并获得枚举回:

EnumType enumType = (EnumType)bundle.getSerializable("enum_key"); 
4

另一种选择:

public enum DataType implements Parcleable { 
SIMPLE, COMPLEX; 

public static final Parcelable.Creator<DataType> CREATOR = new Creator<DataType>() { 

    @Override 
    public DataType[] newArray(int size) { 
     return new DataType[size]; 
    } 

    @Override 
    public DataType createFromParcel(Parcel source) { 
     return DataType.values()[source.readInt()]; 
    } 
}; 

@Override 
public int describeContents() { 
    return 0; 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeInt(this.ordinal()); 
} 

}

+0

您可以使用'putSerializable(key,value)'/'(Type)getSerializable(key)'或'putString(key,value.name())'/'Type.valueOf(getString(key))',Parcelable这里的实现是多余的和荒谬的。 – 2017-08-19 10:17:33

0

一种简单的方法,分配整数值来枚举

参见下面的示例:

public enum MyEnum { 

    TYPE_ONE(1), TYPE_TWO(2), TYPE_THREE(3); 

    private int value; 

    MyEnum(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return value; 
    } 

} 

发送侧:

Intent nextIntent = new Intent(CurrentActivity.this, NextActivity.class); 
nextIntent.putExtra("key_type", MyEnum.TYPE_ONE.getValue()); 
startActivity(nextIntent); 

接收侧:

Bundle mExtras = getIntent().getExtras(); 
int mType = 0; 
if (mExtras != null) { 
    mType = mExtras.getInt("key_type", 0); 
} 

/* OR 
    Intent mIntent = getIntent(); 
    int mType = mIntent.getIntExtra("key_type", 0); 
*/ 

if(mType == MyEnum.TYPE_ONE.getValue()) 
    Toast.makeText(NextActivity.this, "TypeOne", Toast.LENGTH_SHORT).show(); 
else if(mType == MyEnum.TYPE_TWO.getValue()) 
    Toast.makeText(NextActivity.this, "TypeTwo", Toast.LENGTH_SHORT).show(); 
else if(mType == MyEnum.TYPE_THREE.getValue()) 
    Toast.makeText(NextActivity.this, "TypeThree", Toast.LENGTH_SHORT).show(); 
else 
    Toast.makeText(NextActivity.this, "Wrong Key", Toast.LENGTH_SHORT).show(); 
+0

最臃肿和容易出错的方式。 – 2017-08-19 10:18:58

0

我想转换枚举为int(正常枚举),然后捆绑设置在了最简单的方法。像这样的代码的意图:

myIntent.PutExtra("Side", (int)PageType.Fornt); 

然后检查状态:

int type = Intent.GetIntExtra("Side",-1); 
if(type == (int)PageType.Fornt) 
{ 
    //To Do 
} 

而且对所有枚举类型不行!

10

我使用kotlin。

companion object { 

     private enum class Mode { 
      MODE_REFERENCE, 
      MODE_DOWNLOAD 
     } 
} 

然后放入意图:

intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name) 

当你净得值:

mode = Mode.valueOf(intent.getStringExtra(KEY_MODE)) 
1

有一点要注意的 - 如果你正在使用bundle.putSerializableBundle到被添加到通知中,您可能会遇到以下问题:

*** Uncaught remote exception! (Exceptions are not yet supported across processes.) 
    java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object. 

... 

要解决这个问题,你可以做到以下几点:

public enum MyEnum { 
    TYPE_0(0), 
    TYPE_1(1), 
    TYPE_2(2); 

    private final int code; 

    private MyEnum(int code) { 
     this.code = navigationOptionLabelResId; 
    } 

    public int getCode() { 
     return code; 
    } 

    public static MyEnum fromCode(int code) { 
     switch(code) { 
      case 0: 
       return TYPE_0; 
      case 1: 
       return TYPE_1; 
      case 2: 
       return TYPE_2; 
      default: 
       throw new RuntimeException(
        "Illegal TYPE_0: " + code); 
     } 
    } 
} 

然后可以像这样使用:

// Put 
Bundle bundle = new Bundle(); 
bundle.putInt("key", MyEnum.TYPE_0.getCode()); 

// Get 
MyEnum myEnum = MyEnum.fromCode(bundle.getInt("key")); 
相关问题