java - 在枚举上写入 Parcelable 会使应用程序崩溃

标签 java android enums parcelable

这一行是 dest.writeParcelable(department, flags); ,导致应用程序在我通过 Intent 打包对象时崩溃。

当我评论该行时,应用程序会通过,但当然我没有部门值。

public class User implements Parcelable {

    public String id;
    public String name;
    public String email;
    public Department department;

    // other implementations of Parcelable 

protected UserVO(Parcel in) {
    id = in.readString();
    name = in.readString();
    email = in.readString();
    department = in.readParcelable(Department.class.getClassLoader());
}


    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(id);
        dest.writeString(name);
        dest.writeString(email);
        dest.writeParcelable(department, flags); // crashes
    }
}

部门枚举

public enum Department implements Parcelable {

    SALES("Sales", 1),
    HR("Human Resources", 2),
    SHIPPING("Shipping", 3),

    public final String name;
    public final int ordinal;

    Department(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    Department(Parcel in) {
        name = in.readString();
        ordinal = in.readInt();
    }

    public static final Creator<Department> CREATOR = new Creator<Department>() {
        @Override
        public Department createFromParcel(Parcel in) {
            return Department.valueOf(in.readString()); // crash
            //return new DeptEnum(in); // android studio generated code but has error: enum types may not be instantiated
        }

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

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeInt(ordinal);
    }
}

错误

No enum constant Department.Sales

我从中得到了帮助answer对于行 return Department.valueOf(in.readString());

<小时/>

观察

我想它必须同时具有名称和序数值,我的枚举类型并不像链接的答案中那样简单,不知何故我需要从包裹创建一个枚举。

public Department createFromParcel(Parcel in) {
    Log.d("abc", "createFromParcel: " + in.readString()); // returns null
    Log.d("abc", "createFromParcel: " + in.readInt()); // returns 127 or 128
    return SHIPPING; // hard coded value works but of course not a solution
}

最佳答案

您不需要打包序数。单独对名称执行 valueOf 就可以了

但是,valueOf 的参数必须完全匹配枚举定义的名称。

例如,这适用于销售和运输,但不适用于人力资源

Department.valueOf(in.readString().toUpperCase());
<小时/>

您需要的解决方案是循环 Department.values() 并将值的每个名称字段与 in.readString() 结果进行比较

How can I lookup a Java enum from its String value?

或者您可以像这样使用序数,尽管您正在复制序数信息并且必须保证枚举具有连续的数字

 return Department.values()[in.readInt() - 1]

关于java - 在枚举上写入 Parcelable 会使应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58550529/

相关文章:

java - Spring mvc标签表单保存对象

c# - 每个枚举数组都实现了 IEnumerable<EveryOtherEnum>。我该如何解决这个问题?

python - Python 中枚举的枚举?

java - 关闭嵌套流也会关闭其父流吗?

java - 如何在 Wicket 中制作可点击的表格列标题

android - apache中的StringUtils.rightPad()在android中抛出NoSuchMethodError

android - 在android中动态注册/注销广播接收器

javascript - 如何在 expo 应用程序中处理共享 Intent (发送图像)?

c# - 如何强制派生类覆盖基类的枚举?

java - JCE 提供商的算法是如何定义的?