2010-07-20 34 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")); 
相關問題