zoukankan      html  css  js  c++  java
  • enum类型被intent所携带时需要注意的地方

            一般我们在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楼说的:

    [java] view plaincopy
     
    1. public enum MyEnum implements Parcelable {  
    2.     VALUE;  
    3.   
    4.     @Override  
    5.     public int describeContents() {  
    6.         return 0;  
    7.     }  
    8.   
    9.     @Override  
    10.     public void writeToParcel(final Parcel dest, final int flags) {  
    11.         dest.writeInt(ordinal());  
    12.     }  
    13.   
    14.     public static final Creator<MyEnum> CREATOR = new Creator<MyEnum>() {  
    15.         @Override  
    16.         public MyEnum createFromParcel(final Parcel source) {  
    17.             return MyEnum.values()[source.readInt()];  
    18.         }  
    19.   
    20.         @Override  
    21.         public MyEnum[] newArray(final int size) {  
    22.             return new MyEnum[size];  
    23.         }  
    24.     };  
    25. }  
    26.   
    27. 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类的源代码里这么写的:

    [java] view plaincopy
     
    1. public abstract class Enum<E extends Enum<E>> implements Serializable, Comparable<E> {  
    2. ... ...  
    3. }  


            之后你的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成员时可以这样:

    [java] view plaincopy
     
    1. private Father1(Parcel in) {  
    2.     mField = in.readInt();  
    3.     mMyEnum = MyEnum.CREATOR.createFromParcel(in);  
    4. }  
    5.   
    6. public void writeToParcel(Parcel dest, int flags) {  
    7.     dest.writeInt(mField);  
    8.     mMyEnum.writeToParcel(dest, flags);  
    9. }  

            经测试,也可以把enum传递出去。

            既然上述MyEnum的写法可以适应enum作为Parcelable类成员来传递,而不能作为单独的对象来传递,要兼得二者该如何做?

            首先,MyEnum不需实现Parcelable接口,单独传递MyEnum对象时就用Intent.putExtra(String, Serializable)。

            然后把MyEnum的createFromParcel()和writeToParcel()的代码整合进Father类,代码片段(变量名有改动):

    [java] view plaincopy
     
    1. private Father2(Parcel in) {  
    2.     mField = in.readInt();  
    3.     mAnotherEnum = AnotherEnum.values()[in.readInt()];  
    4. }  
    5.   
    6. public static final Parcelable.Creator<Father2> CREATOR = new Parcelable.Creator<Father2>() {  
    7.   
    8.     public Father2 createFromParcel(Parcel in) {  
    9.         return new Father2(in);  
    10.     }  
    11.   
    12.     @Override  
    13.     public Father2[] newArray(int size) {  
    14.         return new Father2[size];  
    15.     }  
    16.   
    17. };  
    18.   
    19. @Override  
    20. public void writeToParcel(Parcel dest, int flags) {  
    21.     dest.writeInt(mField);  
    22.     dest.writeInt(mAnotherEnum.ordinal());  
    23. }  

            再用Intent.putExtra(String, Parcelable)来传Father2对象就可以了。

            再谈一下Enum类的values()方法,这个方法是无法通过eclipse查看到的,它的定义在这里,它返回所有的定义过的枚举值,enum的底层实现就是定义从0到N的数个整数,只不过为每个整数取了个别名,一个enum变量就是这数个整数之一,这个enum变量的ordinal()方法就是返回其在这数个整数中的位置。values()静态方法返回一个包含这数个整数的数组。

    给出示例代码(免积分下载),在MainActivity.java三处注释的地方,分别解注释再运行,就会认识得比较清楚了。

  • 相关阅读:
    Python学习日记(一)——初识Python
    读《乌合之众》
    用WPF做了几个小游戏
    《HeadFirst设计模式》读后感——对学习设计模式的一些想法
    设计模式C#实现(九)——工厂方法模式和简单工厂
    设计模式C#实现(八)——原型模式
    设计模式C#实现(七)——生成器模式
    设计模式C#实现(六)——单例模式
    《小强升职记》读后感和思维导图
    《魔鬼搭讪学》《魔鬼约会学》读后感
  • 原文地址:https://www.cnblogs.com/exmyth/p/4942646.html
Copyright © 2011-2022 走看看