Search code examples
javaandroidarraylistparcelableparcel

Parcelable containing an ArrayList of itself


I'm trying to pass a list of Categories from an Activity to another. I've implemented Parcelable on the class but it's crashing the app every time. Note: the activity works when not passing that extra. Note 2: I can't see any log, just so slow and suddenly "D/AndroidRuntime﹕ Shutting down VM"

This is the parcel:

public  class   Category implements Parcelable{

private String categoryId;
private String name;
private boolean active;
private String slug;
private String externalId;
private String parentId;
private Integer level;
private String categoryTreeNodeId;
private ArrayList<Category> children;


public Category() {}

// Getters and Setters...

@Override
public int describeContents() {
    // ignore for now
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(categoryId);
    dest.writeString(name);
    dest.writeByte((byte) (active ? 1 : 0));
    dest.writeString(slug);
    dest.writeString(externalId);
    dest.writeString(parentId);
    dest.writeInt(level);
    dest.writeString(categoryTreeNodeId);
    dest.writeTypedList(children);
}

/** Static field used to regenerate object, individually or as arrays */
public static final Parcelable.Creator<Category> CREATOR = new Parcelable.Creator<Category>() {
    public Category createFromParcel(Parcel pc) {
        return new Category(pc);
    }
    public Category[] newArray(int size) {
        return new Category[size];
    }
};

/**Ctor from Parcel, reads back fields IN THE ORDER they were written */
public Category(Parcel in){
    categoryId = in.readString();
    name = in.readString();
    active = in.readByte() != 0;
    slug = in.readString();
    externalId = in.readString();
    parentId = in.readString();
    level =  in.readInt();
    categoryTreeNodeId = in.readString();
    in.readTypedList(children, Category.CREATOR);
}

}

This is how I call the activity:

ArrayList<Category> list = currentCategory.getChildren();
    intent.putParcelableArrayListExtra(SubCategoryActivity.EXTRA_CATEGORY_LIST, list);
    intent.putExtra(SubCategoryActivity.EXTRA_CURRENT_CAT_NAME, currentCategory.getName());
    context.startActivity(intent);

The EXTRA_CURRENT_CAT_NAME is just a String and it's working perfectly.

I believe the problem is in the ArrayList. Any advice or experiences doing something similar?

Thanks.

The only log I get is:

08-04 17:56:21.529 30543-30543/com.example.test D/AndroidRuntime﹕ Shutting down VM 08-04 17:56:41.554 30543-30552/com.example.test I/art﹕ Thread[5,tid=30552,WaitingInMainSignalCatcherLoop,Thread*=0xb81e22d0,peer=0x12c00080,"Signal Catcher"]: reacting to signal 3 08-04 17:56:41.554 30543-30552/com.example.test I/art﹕ [ 08-04 17:56:41.754 787: 809 I/Process ] Sending signal. PID: 787 SIG: 3


Solution

  • Your problem is caused by reading the typed list into a null container:

    in.readTypedList(children, Category.CREATOR);
    

    It's a bit confusing, but the use case for readTypedList requires that the List parameter passed in be non-null. I would suggest changing this to use:

    children = in.createTypedArrayList(Category.CREATOR);
    

    This will also maintain the null value if the list is null at the time that it is written to the parcel.