Search code examples
androidstack-overflowparcelableparcel

Getting stack overflow error in Android Parcelable methods


I have two classes that implement Parcelable:

public class A implements Parcelable {
    private List<B> bList;

    ... //everything else omitted

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeTypedList(this.bList);
    }

}

and then

public class B implements Parcelable {
    private A a;

    ... //everything else omitted

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(this.a, flags);
    }

}

In other words A has a list of B objects and each B holds a reference to the A object.

However I've just noticed a situation where during a save instance state call, the app blows up the stack because I suspect it's recursively calling these Parcel writing functions over and over again between the two.

Is there any way to write these to the Parcel without blowing up the stack?


Solution

  • Given the things you mentioned in comments, it sounds like you will always start by unparceling an instance of A, so you have this available when unparceling B. In that case, don't write B.a to the Parcel; instead have A set B.a on all the elements in bList when you finish unparceling A.

    public class A implements Parcelable {
        private List<B> bList;
    
        /* ... */
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeTypedList(this.bList);
        }
    
        // called by your Parcelable.Creator
        private A(Parcel in) {
            bList = new ArrayList<>();
            in.readTypedList(bList, B.CREATOR);
            for (B b : bList) {
                b.a = this; // or b.setA(this)
            }
        }
    }
    
    public class B implements Parcelable {
        private A a;
    
        /* ... */
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            // write everything EXCEPT a
        }
    
        // called by your Parcelable.Creator
        private B(Parcel in) {
            // Read everything EXCEPT a
        }
    }
    

    That said, you might also examine why this circular dependency exists and see if there's some logical restructuring of your code that can break this cycle. Without knowing anything about your classes or how they are used, I can't really provide any guidance beyond that.