How to pass a parcelable object that contains a list of objects?

AndroidAndroid ActivityAndroid Intent

Android Problem Overview


I have created a Parcelable object below, my object contains a List of Products. In my constructor how do I handle re-creating my Parcelable for the List?

I have checked all of the methods available from the parcel and all that is available is readArrayList(ClassLoader). I'm not sure if this is the best approach, your advice would really be appreciated.

public class Outfits implements Parcelable {
	
	private String url;
	private String name;
	private List<Product> products;

	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Product> getProducts() {
		return products;
	}
	public void setProducts(List<Product> products) {
		this.products = products;
	}
	
	public void writeToParcel(Parcel dest, int flags) {
		Log.v("", "writeToParcel..." + flags);
		dest.writeString(url);
		dest.writeString(name);
		dest.writeList(products);
	}
	
	
	public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
		public Outfits createFromParcel(Parcel in) {
			return new Outfits(in);
		}

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

	@Override
	public int describeContents() {
		return 0;
	}
	
    /*** Here how do I populate my List of Products ***/
	private Outfits(Parcel in) {
		url = in.readString();
		name = in.readString();
		products = in.read ???????;
	}
}

Android Solutions


Solution 1 - Android

If class Product is compatible with parcelable protocol, following should work according to documentation.

products = new ArrayList<Product>();
in.readList(products, Product.class.getClassLoader());

Solution 2 - Android

First, your Product object must implements Parcelable.

And then, use dest.writeTypedList(products) in writeToParcel() method.

Finally, use following code to parse the list:

products = new ArrayList<Product>();
in.readTypedList(products, Product.CREATOR);

For more infomation, please reference the Official Document:

Solution 3 - Android

In my personal experience, http://www.parcelabler.com/ is an amazing site for this. You just create your class, and copy paste it into the website, and it generates a Parcelable version of your class.

I tested it with a class named "Theme" that contained the following variables:

private String name;
private int image;
private List<Card> cards;

The writeToParcel function becomes:

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeInt(image);
    if (cards == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeList(cards);
    }
}

generated constructor:

protected Theme(Parcel in) {
    name = in.readString();
    image = in.readInt();
    if (in.readByte() == 0x01) {
        cards = new ArrayList<Card>();
        in.readList(cards, Card.class.getClassLoader());
    } else {
        cards = null;
    }
}

EDIT: make sure that the Card object is also Parcelable!

Solution 4 - Android

This should work:

in.readTypedList(products, Product.CREATOR);

Solution 5 - Android

Here you go...

Make sure "Products.java" should be extended with Parcelable

Step 1:

 private List<Products> products; 

Step 2:

private Outfits(Parcel in) {
    products = in.createTypedArrayList(Products.CREATOR);
}

Step 3:

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

Solution 6 - Android

implement Parcelable on the Product class as well and then

in.readList(this.list, Product.class.getClassLoader());

if any of the above solutions didn't work.

Solution 7 - Android

The other way is to use readValue&writeValue.

protected Product (Parcel in) {
        ...
        in.readValue(this.getClass().getClassLoader());
    }

@Override
public void writeToParcel(Parcel parcel, int i) {
    ...
    parcel.writeValue(**list**);
}

Items of the list should implement Parcelable

Solution 8 - Android

Assuming the Product is implementing Parcelable, you can use this for writing:

dest.writeValue(products);

and this for reading:

products = (List<Product>) in.readValue(Product.class.getClassLoader());

Solution 9 - Android

Product must be implements Parcelable

  Product class implements  Parcelable {
          ......
  }

Then write you object contains list like

public class Outfits implements Parcelable {

     private String url;
     private String name;
     private List<Product> products;
   
     public Outfits (Parcel pi) {

        bookName = p.readString();
        bookId = p.readInt();
        isColor = p.readInt() == 1;

        //use this well be get err
        //products=p.readArrayList(Thread.currentThread().getContextClassLoader());

        //Pass list use this 
        products= in.createTypedArrayList(Product.CREATOR);

      }
  
            ...get and set...

     public void writeToParcel(Parcel dest, int flags) {
        
        
        dest.writeString(url);
        dest.writeString(name);
        
        //use this will no working
        //dest.writeList(products);

        //Parcelable list
        out.writeTypedList(products);

     }
   
 }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionByronView Question on Stackoverflow
Solution 1 - AndroidAlex GitelmanView Answer on Stackoverflow
Solution 2 - AndroidcodezjxView Answer on Stackoverflow
Solution 3 - AndroidPieter DesseynView Answer on Stackoverflow
Solution 4 - Androiduser3875399View Answer on Stackoverflow
Solution 5 - AndroidShyam KumarView Answer on Stackoverflow
Solution 6 - AndroidFaisal NaseerView Answer on Stackoverflow
Solution 7 - AndroidBlackRainbowView Answer on Stackoverflow
Solution 8 - AndroidarenaqView Answer on Stackoverflow
Solution 9 - AndroidVen RenView Answer on Stackoverflow