似乎Parcelable並沒有像Serializable那樣正常處理循環引用。在下面的例子中,酒吧的序列化工作得很好,但它寫入包裹導致計算器:使用帶有循環引用的Parcelable
I/TestRunner(1571): java.lang.StackOverflowError
I/TestRunner(1571): at android.os.Parcel.writeParcelable(Parcel.java:1106)
I/TestRunner(1571): at android.os.Parcel.writeValue(Parcel.java:1029)
I/TestRunner(1571): at com.XXX.util.ParcelableTest$Bar.writeToParcel(ParcelableTest.java:209)
I/TestRunner(1571): at android.os.Parcel.writeParcelable(Parcel.java:1106)
I/TestRunner(1571): at android.os.Parcel.writeValue(Parcel.java:1029)
I/TestRunner(1571): at com.XXX.util.ParcelableTest$Baz.writeToParcel(ParcelableTest.java:246)
I/TestRunner(1571): at android.os.Parcel.writeParcelable(Parcel.java:1106)
I/TestRunner(1571): at android.os.Parcel.writeValue(Parcel.java:1029)
I/TestRunner(1571): at com.XXX.util.ParcelableTest$Bar.writeToParcel(ParcelableTest.java:209)
I/TestRunner(1571): at android.os.Parcel.writeParcelable(Parcel.java:1106)
I/TestRunner(1571): at android.os.Parcel.writeValue(Parcel.java:1029)
public void testCircular() throws Exception {
final Bar bar = new Bar();
final Baz baz = new Baz(bar);
bar.baz = baz;
// First, serialize
final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
new ObjectOutputStream(bytes).writeObject(bar);
final ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes.toByteArray());
final Bar bar2 = (Bar) new ObjectInputStream(bytesIn).readObject();
assertNotNull(bar2);
assertNotNull(bar2.baz);
assertEquals(bar2, bar2.baz.bar);
// Now try same thing using parcelable
final Parcel p = Parcel.obtain();
p.writeValue(bar); // FAIL! StackOverflowError
p.setDataPosition(0);
final Bar bar3 = (Bar) p.readValue(Bar.class.getClassLoader());
assertNotNull(bar3);
assertNotNull(bar3.baz);
assertEquals(bar3, bar3.baz.bar);
}
protected static class Bar implements Parcelable, Serializable {
private static final long serialVersionUID = 1L;
public static final Parcelable.Creator<Bar> CREATOR = new Parcelable.Creator<Bar>() {
public Bar createFromParcel(Parcel source) {
final Bar f = new Bar();
f.baz = (Baz) source.readValue(Bar.class.getClassLoader());
return f;
}
public Bar[] newArray(int size) {
throw new UnsupportedOperationException();
}
};
public Baz baz;
public Bar() {
}
public Bar(Baz baz) {
this.baz = baz;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int ignored) {
dest.writeValue(baz);
}
}
protected static class Baz implements Parcelable, Serializable {
private static final long serialVersionUID = 1L;
public static final Parcelable.Creator<Baz> CREATOR = new Parcelable.Creator<Baz>() {
public Baz createFromParcel(Parcel source) {
final Baz f = new Baz();
f.bar = (Bar) source.readValue(Baz.class.getClassLoader());
return f;
}
public Baz[] newArray(int size) {
throw new UnsupportedOperationException();
}
};
public Bar bar;
public Baz() {
}
public Baz(Bar bar) {
this.bar = bar;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int ignored) {
dest.writeValue(bar);
}
}
我在試圖港口一些代碼使用序列化到使用循環引用Parcelable。用Parcelable處理這個問題有沒有好的策略?
你有沒有想過這個? – 2010-11-10 03:24:43
不幸的是,沒有 – emmby 2010-11-11 21:25:02