Reputation: 2210
This line is dest.writeParcelable(department, flags);
causing the app to crash as I parcel the object via the intent.
When I comment the line, the app goes through but of course I don't have the department value.
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
}
}
Department Enum
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);
}
}
Error
No enum constant Department.Sales
I took the help from this answer for the line return Department.valueOf(in.readString());
Observation
I guess it has to do something with having both name and ordinal values, my enum type is not simple as in the linked answer, somehow I need to create an enum from 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
}
Upvotes: 0
Views: 801
Reputation: 191725
You don't need to parcel the ordinal. Doing valueOf alone on the name would be fine
However, the parameter of valueOf must match exactly the enum defined name.
For example, this would work for sales and shipping, but not HR
Department.valueOf(in.readString().toUpperCase());
The solution you need is to loop over Department.values()
and compare each name field of the values with the in.readString() result
How can I lookup a Java enum from its String value?
Or you could use the ordinal instead like so, although you're duplicating ordinal information and you'd have to guarantee that the enums have sequential numbers
return Department.values()[in.readInt() - 1]
Upvotes: 1