Java 将带有字符串的枚举写入地块

Java 将带有字符串的枚举写入地块,java,android,enums,parcelable,Java,Android,Enums,Parcelable,我有这样的包裹枚举: public enum Option implements Parcelable { DATA_BASE, TRIPS, BIG_PHOTOS, OLD_PHOTOS, FILTERS_IMAGES, CATEGORIES_IMAGES, PAGES, SOUNDS, PUBLIC_TRANSPORT, MAPS; public static final Parcelable.Creator<Option&

我有这样的包裹枚举:

 public enum Option implements Parcelable {

    DATA_BASE, TRIPS, BIG_PHOTOS,
    OLD_PHOTOS, FILTERS_IMAGES,
    CATEGORIES_IMAGES, PAGES,
    SOUNDS, PUBLIC_TRANSPORT, MAPS;        

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

        public Option createFromParcel(Parcel in) {
            return Option.values()[in.readInt()];
        }

        public Option[] newArray(int size) {
            return new Option[size];
        }

    };

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

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(ordinal());
    }
}
public enum选项实现可包裹{
数据库、旅行、大照片、,
旧照片、过滤器、图像、,
类别、图像、页面、,
声音、公共交通、地图;
public static final Parcelable.Creator=新建Parcelable.Creator(){
公共选项createFromParcel(地块在中){
返回选项.values()[in.readInt()];
}
公共选项[]新数组(整数大小){
返回新选项[大小];
}
};
@凌驾
公共int描述内容(){
返回0;
}
@凌驾
公共无效写入包(包出,内部标志){
out.writeInt(序数());
}
}
现在我修改了它,它看起来像:

 public enum Option implements Parcelable {

    DATA_BASE("Database"), TRIPS("Trips"), BIG_PHOTOS("BigPhotos"),
    OLD_PHOTOS("OldPhotos"), FILTERS_IMAGES("FiltersImages"),
    CATEGORIES_IMAGES("CategoriesImages"), PAGES("Pages"),
    SOUNDS("Sounds"), PUBLIC_TRANSPORT("PublicTransport"), MAPS("Maps");

    private String option;

    Option(String option){
        this.option = option;
    }

    public String getName(){
        return option;
    }

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

        public Option createFromParcel(Parcel in) {
            //...
        }

        public Option[] newArray(int size) {
            //...
        }

    };

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

    @Override
    public void writeToParcel(Parcel out, int flags) {
        //...
    }
}
public enum选项实现可包裹{
数据库(“数据库”)、旅行(“旅行”)、大照片(“大照片”),
旧照片(“旧照片”)、过滤器图像(“过滤器图像”),
类别图像(“分类图像”)、页面(“页面”),
声音(“声音”)、公共交通(“公共交通”)、地图(“地图”);
私有字符串选项;
选项(字符串选项){
this.option=选项;
}
公共字符串getName(){
返回选项;
}
public static final Parcelable.Creator=新建Parcelable.Creator(){
公共选项createFromParcel(地块在中){
//...
}
公共选项[]新数组(整数大小){
//...
}
};
@凌驾
公共int描述内容(){
返回0;
}
@凌驾
公共无效写入包(包出,内部标志){
//...
}
}

如何在此枚举中实现writeToParcel()、createFromParcel()和newArray()?我需要它来传递额外的意图

如果使枚举
可打包的唯一原因是将其以
意图
的形式传递,则不需要这样做。枚举是可序列化的,因此您可以像这样传递它:

intent.putExtra("EnumValue", Option.DATA_BASE);
并使用以下方法检索:

Option myEnum = (Option) intent.getSerializableExtra("EnumValue");
我通过以下方式解决了这个问题:

public enum Option implements Parcelable {

    DATA_BASE("Database"), TRIPS("Trips"), BIG_PHOTOS("BigPhotos"),
    OLD_PHOTOS("OldPhotos"), FILTERS_IMAGES("FiltersImages"),
    CATEGORIES_IMAGES("CategoriesImages"), PAGES("Pages"),
    SOUNDS("Sounds"), PUBLIC_TRANSPORT("PublicTransport"), MAPS("Maps");

    private String option;

    Option(String option){
        this.option = option;
    }

    public String getName(){
        return option;
    }

    private void setOption(String option){
        this.option = option;
    }

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

        public Option createFromParcel(Parcel in) {
            Option option = Option.values()[in.readInt()];
            option.setOption(in.readString());
            return option;
        }

        public Option[] newArray(int size) {
            return new Option[size];
        }

    };

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

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(ordinal());
        out.writeString(option);
    }
}
public enum选项实现可包裹{
数据库(“数据库”)、旅行(“旅行”)、大照片(“大照片”),
旧照片(“旧照片”)、过滤器图像(“过滤器图像”),
类别图像(“分类图像”)、页面(“页面”),
声音(“声音”)、公共交通(“公共交通”)、地图(“地图”);
私有字符串选项;
选项(字符串选项){
this.option=选项;
}
公共字符串getName(){
返回选项;
}
私有void setOption(字符串选项){
this.option=选项;
}
public static final Parcelable.Creator=新建Parcelable.Creator(){
公共选项createFromParcel(地块在中){
Option=Option.values()[in.readInt()];
option.setOption(in.readString());
返回选项;
}
公共选项[]新数组(整数大小){
返回新选项[大小];
}
};
@凌驾
公共int描述内容(){
返回0;
}
@凌驾
公共无效写入包(包出,内部标志){
out.writeInt(序数());
out.减记资本(期权);
}
}

这是一个老问题,但有一个更好的解决方案:

dest.writeString(myEnumOption.name());


这可能是晚了,但它可能会帮助其他人,所以我仍然会张贴这篇文章

  • 正如前面提到的,将setter设置为enum的成员是一种不好的做法。如果您需要该成员,请将其设置为最终成员(不包括设置者的可能性)

  • 您不需要将该成员(在本例中为字符串“option”)保存到地块中,并在重新创建时将其恢复

  • 我的执行情况如下

    public enum Option implements Parcelable {
    
        DATA_BASE("Database"), TRIPS("Trips"), BIG_PHOTOS("BigPhotos"),
        OLD_PHOTOS("OldPhotos"), FILTERS_IMAGES("FiltersImages"),
        CATEGORIES_IMAGES("CategoriesImages"), PAGES("Pages"),
        SOUNDS("Sounds"), PUBLIC_TRANSPORT("PublicTransport"), MAPS("Maps");
    
        private final String option;
    
        Option(String option){
            this.option = option;
        }
    
        public String getName() {
            return option;
        }
    
        public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {
    
            public Option createFromParcel(Parcel in) {
                return values()[in.readInt()];
            }
    
            public Option[] newArray(int size) {
                return new Option[size];
            }
    
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(ordinal());
        }
    
    }
    
    public enum选项实现可包裹{
    数据库(“数据库”)、旅行(“旅行”)、大照片(“大照片”),
    旧照片(“旧照片”)、过滤器图像(“过滤器图像”),
    类别图像(“分类图像”)、页面(“页面”),
    声音(“声音”)、公共交通(“公共交通”)、地图(“地图”);
    私有最终字符串选项;
    选项(字符串选项){
    this.option=选项;
    }
    公共字符串getName(){
    返回选项;
    }
    public static final Parcelable.Creator=新建Parcelable.Creator(){
    公共选项createFromParcel(地块在中){
    返回值()[in.readInt()];
    }
    公共选项[]新数组(整数大小){
    返回新选项[大小];
    }
    };
    @凌驾
    公共int描述内容(){
    返回0;
    }
    @凌驾
    公共无效写入包(包出,内部标志){
    out.writeInt(序数());
    }
    }
    
    我将它作为列表传递,所以我需要它。如果您使用的是标准列表实现之一(例如ArrayList或LinkedList),那么这些实现是可序列化的。如果您的列表是可序列化的,并且您的内容是可序列化的,那么您仍然可以使用此方法。这取决于您正在使用的
    List
    的实现是否是
    Serializable
    。您只需将列表放入对
    intent.putExtra()
    的调用中,当您将其取出时,将其强制转换到选项列表中。当然,不要使用ordinal()将其保留在某个位置。如果更改顺序或插入/删除枚举成员,则数据将出错。在枚举上放置setter可能是解决此问题的最差方法。它完全消除了使用枚举的所有优点使用序数唯一需要注意的是,如果插入条目或对其重新排序,则任何以前保存的值都将被破坏。当像我一样使用名称时,重构也会带来类似的问题,但不太可能被意外更改(例如,自动代码组织)破坏
    public enum Option implements Parcelable {
    
        DATA_BASE("Database"), TRIPS("Trips"), BIG_PHOTOS("BigPhotos"),
        OLD_PHOTOS("OldPhotos"), FILTERS_IMAGES("FiltersImages"),
        CATEGORIES_IMAGES("CategoriesImages"), PAGES("Pages"),
        SOUNDS("Sounds"), PUBLIC_TRANSPORT("PublicTransport"), MAPS("Maps");
    
        private final String option;
    
        Option(String option){
            this.option = option;
        }
    
        public String getName() {
            return option;
        }
    
        public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {
    
            public Option createFromParcel(Parcel in) {
                return values()[in.readInt()];
            }
    
            public Option[] newArray(int size) {
                return new Option[size];
            }
    
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(ordinal());
        }
    
    }