android可parcelable引用另一个parcelable循环依赖

确实很简单的情况,但我找不到任何有关谷歌的东西,所以在这里:

class ContainerClass implements Parcelable { List<ItemClass> _items; (...) public void writeToParcel( Parcel p, int args ) { p.writeList( _items ); (...) } } class ItemClass implements Parcelable { ContainerClass _containerRef; (...) public void writeToParcel( Parcel p, int args ) { p.writeParcelable( _containerRef ); (...) } } 

这将不可避免地循环和溢出堆栈。

我的问题:我该如何处理这种情况:我必须将上述types的对象传递给新的Activity。

(对于CommonsWare)Parcelable实现确实似乎没有检查,并避免循环依赖。 堆栈跟踪的类名取代上面的名字:

 08-12 10:17:45.233 5590-5590/com.package E/AndroidRuntime: FATAL EXCEPTION: main java.lang.StackOverflowError at com.package.ContainerClass.writeToParcel(ContainerClass.java:139) at android.os.Parcel.writeParcelable(Parcel.java:1254) at com.package.ItemClass.writeToParcel(ItemClass.java:182) at android.os.Parcel.writeParcelable(Parcel.java:1254) at android.os.Parcel.writeValue(Parcel.java:1173) at android.os.Parcel.writeList(Parcel.java:622) at com.package.ContainerClass.writeToParcel(ContainerClass.java:144) at android.os.Parcel.writeParcelable(Parcel.java:1254) at com.package.ItemClass.writeToParcel(ItemClass.java:182) at android.os.Parcel.writeParcelable(Parcel.java:1254) at android.os.Parcel.writeValue(Parcel.java:1173) at android.os.Parcel.writeList(Parcel.java:622) 

Solutions Collecting From Web of "android可parcelable引用另一个parcelable循环依赖"

这将不可避免地循环和溢出堆栈。

AFAIK,分包过程不处理圆形对象图 。 我刚刚提出了一个问题,以更好地logging 。

一个解决方法是不做p.writeParcelable( _containerRef ); 。 相反,在ContainerClass ,在您的ContainerClass(Parcel in)构造函数(或者您的CREATOR正在处理它)中,读入_items列表后,遍历该列表并告诉每个孩子关于其父项。

我一直在想更多,并提出了两个解决方法,如果其他人在同一条船上:

1)(受CommonsWare的启发)在链的每个部分上放置一个标志来表示方向向上的层次是有损的,因为ContainerClass的所有项目都不能被恢复。

 class ContainerClass implements Parcelable { boolean _parcelableDownHeirarchy = true; List<ItemClass> _items; (...) private ContainerClass( Parcel in ) { _items = in.readArrayList( ItemClass.class.getClassLoader() ); (...) if ( _parcelableDownHierarchy ) { for ( int i = 0; i < _items.size(); i++ ) _items.get( i ).set_container( this ); } } public void writeToParcel( Parcel p, int args ) { p.writeByte( (byte)_parcelableDownHierarchy ? 1 : 0 ); if ( _parcelableDownHeirarchy ) p.writeList( _items ); (...) } } class ItemClass implements Parcelable { boolean _parcelableDownHeirarchy = true; ContainerClass _containerRef; (...) private ItemClass( Parcel in ) { if ( !_parcelableDownHeirarchy ) { _containerRef = in.readParcelable( ContainerClass.class.getClassLoader() ); //Won't contain item in it's _items list. } } public void writeToParcel( Parcel p, int args ) { p.writeByte( (byte)_parcelableDownHierarchy ? 1 : 0 ); if ( !_parcelableDownHeirarchy ) //Up the heirarchy p.writeParcelable( _containerRef ); (...) } } 

2)滥用解决方法,采用静态哈希表,授予每个对象可以唯一标识它的parcelable属性。 (在我的情况下,我的数据库中的对象的主键)。

 class ContainerClass implements Parcelable { //Leave be } class ItemClass implements Parcelable { HaspMap<Long, ContainerClass> _parents = new HashMap<Long, ContainerClass>(); ContainerClass _containerRef; (...) public long get_PKhash() { /* Return unique identifier */ } private ItemClass( Parcel in ) { (...) assertTrue( (_containerRef = _parents.remove( get_PKhash() )) != null ); } public void writeToParcel( Parcel p, int args ) { (...)//Don't write _containerRef _parents.put( this.get_PKhash, _containerRef ); } }