enum類型被intent所攜帶時需要注意的地方
https://blog.csdn.net/tedzyc/article/details/8373399
2012年12月22日 17:18:30 tedzyc 閱讀數:13847
一般我們在Activity之間傳遞對象時多用Parcelable。比如寫一個class,在這個class上标明implements Parcelable并實作接口就可以用Intent.putExtra(String, Parcelable)了。對于傳遞enum對象,假設也采用此方法,即像http://stackoverflow.com/questions/2836256/passing-enum-or-object-through-an-intent-the-best-solution裡面3樓說的:
-
public enum MyEnum implements Parcelable {
-
VALUE;
-
@Override
-
public int describeContents() {
-
return 0;
-
}
-
@Override
-
public void writeToParcel(final Parcel dest, final int flags) {
-
dest.writeInt(ordinal());
-
}
-
public static final Creator<MyEnum> CREATOR = new Creator<MyEnum>() {
-
@Override
-
public MyEnum createFromParcel(final Parcel source) {
-
return MyEnum.values()[source.readInt()];
-
}
-
@Override
-
public MyEnum[] newArray(final int size) {
-
return new MyEnum[size];
-
}
-
};
-
}
-
You can than use Intent.putExtra(String, Parcelable).
那麼我們先定義一個MyEnum變量a,再調用intent.putExtra("name", a),會報The method putExtra(String, Parcelable) is ambiguous for the type Intent的錯,為何?
因為enum自身實作了Serializable接口,Enum類的源代碼裡這麼寫的:
-
public abstract class Enum<E extends Enum<E>> implements Serializable, Comparable<E> {
-
... ...
-
}
之後你的MyEnum類再實作Parcelable接口,而intent裡面有這樣兩個函數:Intent.putExtra(String, Parcelable)和Intent.putExtra(String, Serializable),你的MyEnum類實作了Serializable和Parcelable兩個接口,在調用Intent.putExtra時,編譯器就不知道該選Intent.putExtra(String, Parcelable)還是Intent.putExtra(String, Serializable),導緻二義性。那麼上面的說法是否真的無用? 其實這種寫法在MyEnum對象作為類Father1的成員時還是可以這麼寫的,我們在Activity間傳Father1,Father1是可以實作Parcelable接口的。Father1内部處理MyEnum成員時可以這樣:
-
private Father1(Parcel in) {
-
mField = in.readInt();
-
mMyEnum = MyEnum.CREATOR.createFromParcel(in);
-
}
-
public void writeToParcel(Parcel dest, int flags) {
-
dest.writeInt(mField);
-
mMyEnum.writeToParcel(dest, flags);
-
}
經測試,也可以把enum傳遞出去。
既然上述MyEnum的寫法可以适應enum作為Parcelable類成員來傳遞,而不能作為單獨的對象來傳遞,要兼得二者該如何做?
首先,MyEnum不需實作Parcelable接口,單獨傳遞MyEnum對象時就用Intent.putExtra(String, Serializable)。
然後把MyEnum的createFromParcel()和writeToParcel()的代碼整合進Father類,代碼片段(變量名有改動):
-
private Father2(Parcel in) {
-
mField = in.readInt();
-
mAnotherEnum = AnotherEnum.values()[in.readInt()];
-
}
-
public static final Parcelable.Creator<Father2> CREATOR = new Parcelable.Creator<Father2>() {
-
public Father2 createFromParcel(Parcel in) {
-
return new Father2(in);
-
}
-
@Override
-
public Father2[] newArray(int size) {
-
return new Father2[size];
-
}
-
};
-
@Override
-
public void writeToParcel(Parcel dest, int flags) {
-
dest.writeInt(mField);
-
dest.writeInt(mAnotherEnum.ordinal());
-
}
再用Intent.putExtra(String, Parcelable)來傳Father2對象就可以了。
再談一下Enum類的values()方法,這個方法是無法通過eclipse檢視到的,它的定義在這裡,它傳回所有的定義過的枚舉值,enum的底層實作就是定義從0到N的數個整數,隻不過為每個整數取了個别名,一個enum變量就是這數個整數之一,這個enum變量的ordinal()方法就是傳回其在這數個整數中的位置。values()靜态方法傳回一個包含這數個整數的數組。
給出示例代碼(免積分下載下傳),在MainActivity.java三處注釋的地方,分别解注釋再運作,就會認識得比較清楚了。