2013-08-11 33 views
8

Raczej prosty scenariusz naprawdę, ale nie mogłem znaleźć nic związanego z Google tak tu idzie:android parcelable przedstawieniu innego parcelable kołową zależność

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); 
    (...) 
    }  
} 

To nieuchronnie pętli i przepełnienie stosu.

Moje pytanie: Jak mam sobie radzić z sytuacją, w której muszę przekazać przedmiot powyższych typów do nowego działania.

(Dla CommonsWare) Rzeczywiste wdrożenie wydaje się nie sprawdzać i unikać zależności cyklicznych. StackTrace z ClassNames zastąpione wyżej nazwami:

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) 

Odpowiedz

1

Byłem rozważała kilka i pochodzą z dwóch obejściach przydatna, jeśli ktoś jest w tej samej łodzi:

1) (Zainspirowany CommonsWare) umieścić flagę na każdej części łańcucha w celu wskazania kierunek W górę heirarchy jest stratna w tym sensie, że wszystkie elementy do ContainerClass nie można przywrócić.

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) hackish obejście, wykorzystując statyczny tabeli mieszania, przyznane każda może być identyfikowany przez to parcelable atrybutów. (W moim przypadku mam klucz podstawowy w mojej bazie danych w obiektach).

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); 
    }  
} 
+0

Skończyło się na wprowadzeniu numeru 2. – Skod

8

To nieuchronnie pętli i poza ten stos.

AFAIK, proces paczkowania nie obsługuje numeru circular object graphs. Właśnie przesłałem an issue to get this better documented.

Jednym z rozwiązań jest niepodanie p.writeParcelable(_containerRef);. Zamiast tego, w ContainerClass, w swoim konstruktorze ContainerClass(Parcel in) (lub niezależnie od tego, czy obsługuje go CREATOR), po przeczytaniu na liście _items, wykonaj iterację na tej liście i powiedz każdemu dziecku o jego rodzica.

+0

To obejście byłoby wspaniałe, gdybym musiał przejść przez ContainerClass. Niestety jest to zbiór instancji ItemClass, które muszę przekazać do działania. Chociaż mogłem zrobić odwrotne, a nie p.writeList, ponieważ tak naprawdę nie potrzebuję tych informacji w tej części mojego programu, ta implementacja powoduje problemy w innych częściach, gdy instancje "Parseled" ContainerClass nie będą mieć _items. – Skod

+0

To rozwiązanie działa dla mnie. – kdroider