在枚举上写入 parcelable 会使应用程序崩溃
write parcelable on enum is crashing the app
这一行 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());
观察
我想它必须同时具有名称和序号值,我的枚举类型并不像链接答案中那样简单,不知何故我需要从 parcel 创建一个枚举。
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 的参数必须完全匹配枚举定义的名称。
例如,这适用于销售和运输,但不适用于 HR
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]
这一行 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());
观察
我想它必须同时具有名称和序号值,我的枚举类型并不像链接答案中那样简单,不知何故我需要从 parcel 创建一个枚举。
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 的参数必须完全匹配枚举定义的名称。
例如,这适用于销售和运输,但不适用于 HR
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]