I haven't understood how to create the code needed to implement correctly the Parcelable
for an object that contains GregorianCalendar
objects.
E.g. for an object User
that contains String name;
and GregorianCalendar creationDate;
, my attempt is this:
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeParcelable(this.creationDate, flags);
}
private User(Parcel in) {
this.name = in.readString();
this.creationDate = in.readParcelable(GregorianCalendar.class.getClassLoader());
}
public static final Creator<User> CREATOR = new Creator<User>() {
public User createFromParcel(Parcel source) {
return new User(source);
}
public User[] newArray(int size) {
return new User[size];
}
};
that unfortunately doesn't work
in writeToParcel()
at the line
dest.writeParcelable(this.creationDate, flags);
get writeParcelable cannot be applied to GregorianCalendar error
in
this.creationDate = in.readParcelable(GregorianCalendar.class.getClassLoader());
get Incompatible types error
How to code correctly the Parcelable
?
EDIT
I have tried some code generators but use different ways and I'm not sure what is the right implementation, the first one use writeValue and readValue in this way:
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeValue(creationDate);
}
protected User(Parcel in) {
name = in.readString();
creationDate = (GregorianCalendar) in.readValue(GregorianCalendar.class.getClassLoader());
}
the second one use
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeSerializable(creationDate);
}
protected User(Parcel in) {
name = in.readString();
creationDate = (GregorianCalendar) in.readSerializable();
}
What is the right way?
You could use the second way since GregorianCalendar
implements Serializable
, and the Parcelable
will work.
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeSerializable(creationDate);
}
protected User(Parcel in) {
name = in.readString();
creationDate = (GregorianCalendar) in.readSerializable();
}
However you MUST NOT serialize GregorianCalendar, because updates in GregorianCalendar
related class can cause issue. Consider the case you load a file that contains GregorianCalendar
objects created with a different API version, the difference in GregorianCalendar
implementation will lead to sure errors, is enough a little difference in serialVersionUID
costant to prevent the correct load of the file.
Use long
parameters to store the millisecond of the date, if you don't want to rewrite your whole application you can easily create a couple of methods to convert from millis to GregorianCalendar
and vice-versa as you need.