It appears that Parcelable doesn\'t gracefully handle circular references like Serializable does. In the following example, the Serialization of Bar works just fine, but writin
Perhaps the answer lies in a more intelligent set of writeToParcel and createFromParcel methods?
Off the top of my head, you could keep a list of objects you had already fully written to a given Parcel and identify them only by a tag (their local identityHashCode(), perhaps). (Note that this is not a global list, it is explicitly per-Parcel; perhaps itself stored via a semi-global Map
? You'd need to be sure the set was forgotten once the parcel was fully written.)
The relevant bit of writeToParcel()
would look something like this:
HashSet set = getWrittenSetFor(dest);
final int tag = identityHashCode();
if (set.contains(tag)) {
// Already sent
dest.writeInt(tag);
} else {
set.put(tag);
dest.writeInt(tag);
dest.writeValue(this);
}
The corresponding createFromParcel()
would be slightly more complex.
I expect there are lurking problems with this method, but it's where I'd start. As I've put it here, it depends on identityHashCode()
being guaranteed to be different for different objects - it usually is on 32-bit JVMs (being the value of the underlying C++ pointer). Plain hashCode()
might be worthwhile (perhaps with the addition of typing information?), or perhaps some sort of serial number.
Another option might be to just plain serialize your objects to a byte[]
and write that into the Parcel
, but it strikes me as a bit inefficient...