Using Parcelable with circular references

前端 未结 2 2035
梦如初夏
梦如初夏 2021-02-04 16:47

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

2条回答
  •  你的背包
    2021-02-04 17:20

    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...

提交回复
热议问题