0

I have a class called SuperMedia that implements Parcelable. One of the fields of the class is an ArrayList children. When I create a Bundle and try to pass a "SuperMedia" object from one activity to another, all the fields get passed fine with the exception of the ArrayList "children" which just shows up as being empty every time.

In my first Activity I do:

 Bundle a = new Bundle();
 a.putParcelable("media",media); //media is an object of type "SuperMedia" and all the "children" have been initialized and added to the array
 final Intent i = new Intent("com.tv.video.subcategories");
 i.putExtra("subcategories", a);

On my Second Activity I do:

  Intent i = getIntent();
  Bundle secondBun = i.getBundleExtra("subcategories");
  SuperMedia media = secondBun.getParcelable("media"); //For some reason the ArrayList"children" field shows up as empty. 

Im not sure why this is happening. If anybody can guide me on the right path that would be greatly appreciated. Below is my SuperMedia class btw.

public class SuperMedia implements Parcelable{

public URI mthumb;
public String mTitle;
public ArrayList<SuperMedia> children = new ArrayList(); 

public SuperMedia(URI thumb, String title) {
    this.mthumb = thumb;
    this.mTitle = title;
}


@Override
public void writeToParcel(Parcel dest, int flags) {
    // TODO Auto-generated method stub
    dest.writeString(mTitle);
    dest.writeString(mthumb.toString());
    dest.writeTypedList(children);

}

public static final Parcelable.Creator<SuperMedia> CREATOR = new Parcelable.Creator<SuperMedia>() {
    public SuperMedia createFromParcel(Parcel in) {
        return new SuperMedia(in);
    }

    public SuperMedia[] newArray(int size) {
        return new SuperMedia[size];
    }
};

private SuperMedia(Parcel in) {
    mTitle = in.readString();
    try {
        mthumb = new URI(in.readString());
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    in.readTypedList(children, SuperMedia.CREATOR);

}

public SuperMedia(){

}

}

aafonso1991
  • 142
  • 9
  • `children` contains instance of `SuperMedia`? or are there descendants of it? – njzk2 May 08 '14 at 18:51
  • @njzk2 It contains descendants – aafonso1991 May 08 '14 at 18:53
  • then it cannot work, as the SuperMedia.CREATOR does not know how to unparcel these. – njzk2 May 08 '14 at 18:54
  • Your code seems to should work. I'm not sure, but try to change `public ArrayList children = new ArrayList();` to `public List children = new ArrayList(); `. – erakitin May 08 '14 at 19:02
  • @erakitin: this does not change anything as ArrayList is a List. Also, the actual issue here is that `SuperMedia implements Parcelable`, but that does not work for anything `extends SuperMedia`, because the `SuperMedia.CREATOR` only can call `new SuperMedia(in)` – njzk2 May 08 '14 at 19:04
  • @njzk2 I tried downcasting, and my child class "Subcategory" and overwrote all the Parcelable methods, but in the childClass doing "in.readTypedList(children, Subcategory.CREATOR)" gives me an error – aafonso1991 May 08 '14 at 19:09
  • yes, because your list is still type `List` isn't it? – njzk2 May 08 '14 at 20:05
  • (Parcelable is far from optimal/obvious once it comes to inheritance. In most cases I would consider not pass the object, but a reference to a database entry, or something like that) – njzk2 May 08 '14 at 20:06
  • You have to read in same order as write and that's what's really wrong. Not the serializable answer. – danny117 May 08 '14 at 20:52
  • @danny117 I was doing that – aafonso1991 May 08 '14 at 22:02

2 Answers2

2

If you want simply pass object through intent then you can make SuperMedia Serializable no need to Parcelable.

public class SuperMedia implements Serializable{...}

put it as

Bundle a = new Bundle(); a.putSerializable("media",media);

and we get it as.

Intent i = getIntent();
Bundle secondBun = i.getBundleExtra("subcategories");
SuperMedia media = (SuperMedia)secondBun.getSerializable("media");

if you really needed Parcelable then may it help you. Arraylist in parcelable object

Community
  • 1
  • 1
Pradeep Kumar
  • 777
  • 6
  • 21
  • Doesn't Parcelable and Serializable do the same thing? My issue is that my arrayList "children" always shows up as empty on the second activity after I pass it – aafonso1991 May 08 '14 at 18:55
  • @Pradeep Parcelable is much faster and more optimized for IPC, which is why it is recommended by android. (People don't just go around adding new ways of doing the same thing just for the thrill of messing with people's head) – njzk2 May 08 '14 at 18:55
  • @PradeepYaduvanshy : however, given the ease of use of Serializable compared to Parcelable, in this case it can be a good alternative, if there are many descendants of SuperMedia – njzk2 May 08 '14 at 19:01
  • @PradeepYaduvanshy Implementing Serializable rather than Parcelable solved the problem. Thank you so much for your help – aafonso1991 May 08 '14 at 20:04
0

Use Bundle's putParcellableArrayList for storing SuperMedia object

Bundle args = new Bundle();
args.putParcelableArrayList("media", "media");

and for restroring

getArguments().getParcelableArrayList("media");

This way will ensure bundle save your list objects as implemented in parcelable instance. Also, be aware of using only ArrayList, other List subclasses not supported.

Gökhan Barış Aker
  • 4,445
  • 5
  • 25
  • 35