When trying to pass a custom object from an activity to a fragment by using a bundle, I kept getting a null bundle when I tried to retrieve it in the fragment. I am using parcels since they are the only option for custom arraylists. Any help appreciated!
To show that my class is parcelable:
public class Exercise implements Parcelable{
private String mName;
private String mMuscleGroup;
private String mType;
private String mEquipment;
private float mWeight;
private int mReps;
private int mSet;
public Exercise(String name, String MuscleGroup, String type, String equipment, float weight, int reps, int set) {
mName = name;
mMuscleGroup = MuscleGroup;
mType = type;
mEquipment = equipment;
mWeight = weight;
mReps = reps;
mSet = set;
}
private Exercise(Parcel in) {
mName = in.readString();
mMuscleGroup = in.readString();
mType = in.readString();
mEquipment = in.readString();
mWeight = in.readFloat();
mReps = in.readInt();
mSet = in.readInt();
}
public static final Creator<Exercise> CREATOR = new Creator<Exercise>() {
#Override
public Exercise createFromParcel(Parcel in) {
return new Exercise(in);
}
#Override
public Exercise[] newArray(int size) {
return new Exercise[size];
}
};
public String getName() {
return mName;
}
public String getMuscleGroup() {
return mMuscleGroup;
}
public String getType() {
return mType;
}
public String getEquipment() {
return mEquipment;
}
public float getWeight() { return mWeight; }
public int getReps() { return mReps; }
public int getSet() { return mSet; }
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(mName);
parcel.writeString(mMuscleGroup);
parcel.writeString(mType);
parcel.writeString(mEquipment);
parcel.writeFloat(mWeight);
parcel.writeInt(mReps);
parcel.writeInt(mSet);
}
}
'''
Activity I am passing bundle from:
#Override
protected void onPause() {
// send ArrayList of exercises to WorkoutsFragment
WorkoutsFragment workoutsFragment = new WorkoutsFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("exercise", exercise);
workoutsFragment.setArguments(bundle);
// clear exercise ArrayList
super.onPause();
}
Fragment receiving bundle:
Bundle bundle = this.getArguments();
if(bundle != null) {
exercise = bundle.getParcelableArrayList("exercise");
}
You need to use bundle.putParcelableArrayList to put Parcelable list objects, not putSerializable
If the types don't match, you get null
Related
I would like to send an array of objects between activities. I want to use the parcelable interface and send the data in an intent. However I keep getting errors. I have been stuck for 2 days. Here are some details about my problem.
Class A
private ProjetUI[] mProjects;
private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent = new Intent(context, ProjetListActivity.class);
intent.putExtra(ProjetListActivity.ARG_PROJECTS, mProjects);
context.startActivity(intent);
}
};
Class B
ProjetUI[] mProjects = getIntent().getParcelableArrayExtra(ARG_PROJECTS);
I get a compilation error "Incompatible types"
After casting to (ProjetUI[]), I get a runtime error "Cannot cast Parcelable[] to ProjetUI[]"
Class Projet
public class ProjetUI implements Parcelable {
private String id;
private String idParent;
private String nom;
private String description;
private List<ProjetColonneUI> colonnes;
private List<VueUI> vues;
private boolean archive;
private String version;
private String commentaire;
private boolean published;
private List<DroitAccesUI> droitAcces;
private String idDossier;
private String typeDossier;
private String idModele;
private List<ProjetDatasetUI> projetDatasets;
protected ProjetUI(Parcel in) {
id = in.readString();
idParent = in.readString();
nom = in.readString();
description = in.readString();
colonnes = in.createTypedArrayList(ProjetColonneUI.CREATOR);
vues = in.createTypedArrayList(VueUI.CREATOR);
archive = in.readInt() == 1;
version = in.readString();
commentaire = in.readString();
published = in.readInt() == 1;
droitAcces = in.createTypedArrayList(DroitAccesUI.CREATOR);
idDossier = in.readString();
typeDossier = in.readString();
idModele = in.readString();
projetDatasets = in.createTypedArrayList(ProjetDatasetUI.CREATOR);
}
public static final Creator<ProjetUI> CREATOR = new Creator<ProjetUI>() {
#Override
public ProjetUI createFromParcel(Parcel in) {
return new ProjetUI(in);
}
#Override
public ProjetUI[] newArray(int size) {
return new ProjetUI[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(getId());
parcel.writeString(getIdParent());
parcel.writeString(getNom());
parcel.writeString(getDescription());
parcel.writeTypedList(getColonnes());
parcel.writeTypedList(getVues());
parcel.writeInt(isArchive() ? 1 : 0);
parcel.writeString(getVersion());
parcel.writeString(getCommentaire());
parcel.writeInt(isPublished() ? 1 : 0);
parcel.writeTypedList(getDroitAcces());
parcel.writeString(getIdDossier());
parcel.writeString(getTypeDossier());
parcel.writeString(getIdModele());
parcel.writeTypedList(getProjetDatasets());
}
}
EDIT
This is the complete stacktrace
The other classes implement parcelable just like ProjeUI class.
Here is an example of another class that has an enum type and an example of an enum that implements parcelable
public class VueRelationUI implements Parcelable {
private String id;
private String idVue;
private String idRelation;
private RelationType typeRelation;
protected VueRelationUI(Parcel in) {
id = in.readString();
idVue = in.readString();
idRelation = in.readString();
typeRelation = in.readParcelable(RelationType.class.getClassLoader());
}
public static final Creator<VueRelationUI> CREATOR = new Creator<VueRelationUI>() {
#Override
public VueRelationUI createFromParcel(Parcel in) {
return new VueRelationUI(in);
}
#Override
public VueRelationUI[] newArray(int size) {
return new VueRelationUI[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(getId());
parcel.writeString(getIdVue());
parcel.writeString(getIdRelation());
parcel.writeParcelable(getTypeRelation(), flags);
}
}
ENUM
public enum RelationType implements Parcelable {
INNER,
OUTER;
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(ordinal());
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<RelationType> CREATOR = new Creator<RelationType>() {
#Override
public RelationType createFromParcel(Parcel parcel) {
return RelationType.values()[parcel.readInt()];
}
#Override
public RelationType[] newArray(int size) {
return new RelationType[size];
}
};
}
Any help would be much appreciated
The problem happens because of the internal implementation of Android's Parcel class. When you start the new activity, all of the intent extras are parceled and then unparceled. When this happens, the Android framework allocates a new Parcelable[], and not a new ProjetUI[]. So you get a ClassCastException when you try to cast it.
Probably the best solution would be to change your code to use ArrayList<ProjetUI> instead of ProjetUI[]. Then you can use Intent.putParcelableArrayListExtra() and getParcelableArrayListExtra() without any problems.
If you can't do that for some reason, then you will have to manually cast the array one element at a time:
Parcelable[] parcelables = getIntent().getParcelableArrayExtra(ARG_PROJECTS);
ProjetUI[] mProjects = new ProjetUI[parcelables.length];
for (int i = 0; i < parcelables.length; ++i) {
mProjects[i] = (ProjetUI) parcelables[i];
}
I'm not able to get list object which has another list in it through parcelable to another activity. Below is my code.
SnipDataEvents.java
public class SnipDataEvents implements Parcelable {
private String title,image,language,bookingUrl,infoUrl,genre;
private List<Venues> venuesList;
public SnipDataEvents(String title,String image,String language,String genre,String bookingUrl,String infoUrl,List<Venues> list){
venuesList = new ArrayList<>();
venuesList.addAll(list);
this.title = title;
this.image = image;
this.language = language;
this.genre = genre;
this.bookingUrl = bookingUrl;
this.infoUrl = infoUrl;
this.venuesList = list;
}
protected SnipDataEvents(Parcel in) {
title = in.readString();
image = in.readString();
language = in.readString();
bookingUrl = in.readString();
infoUrl = in.readString();
genre = in.readString();
in.readTypedList(getVenuesList(),Venues.CREATOR);
}
public static final Creator<SnipDataEvents> CREATOR = new Creator<SnipDataEvents>() {
#Override
public SnipDataEvents createFromParcel(Parcel in) {
return new SnipDataEvents(in);
}
#Override
public SnipDataEvents[] newArray(int size) {
return new SnipDataEvents[size];
}
};
public String getImage() {
return image;
}
public String getTitle() {
return title;
}
public List<Venues> getVenuesList() {
return venuesList;
}
public String getBookingUrl() {
return bookingUrl;
}
public String getGenre() {
return genre;
}
public String getInfoUrl() {
return infoUrl;
}
public String getLanguage() {
return language;
}
public void setVenuesList(List<Venues> venuesList) {
this.venuesList = venuesList;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(title);
parcel.writeString(image);
parcel.writeString(language);
parcel.writeString(bookingUrl);
parcel.writeString(infoUrl);
parcel.writeString(genre);
parcel.writeTypedList(venuesList);
}
}
Venues.java
public class Venues implements Parcelable {
private String name;
//private List<String> showTimes;
public Venues(String name, List<String> showTimes) {
//showTimes = new ArrayList<>();
this.name = name;
//this.showTimes = showTimes;
}
protected Venues(Parcel in) {
name = in.readString();
//showTimes = in.createStringArrayList();
}
public static final Creator<Venues> CREATOR = new Creator<Venues>() {
#Override
public Venues createFromParcel(Parcel in) {
return new Venues(in);
}
#Override
public Venues[] newArray(int size) {
return new Venues[size];
}
};
public String getName() {
return name;
}
//public List<String> getShowTimes() {
// return showTimes;
// }
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
}
}
MainActivity.java
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("snipdataevents",(ArrayList<SnipDataEvents>)snipDataEvents);
intent.putExtras(bundle);
startActivity(intent);
DetailActivity.java
Bundle bundle = getIntent().getExtras();
snipDataEvents = bundle.getParcelableArrayList("snipdataevents");
when I run the code ,in DetailActivity.java bundle.getParcelableArrayList("snipdataevents") returns null
when I removed this
in.readTypedList(getVenuesList(),Venues.CREATOR);
and
parcel.writeTypedList(venuesList);
aboves lines in SnipDataEvents.java
then run, bundle.getParcelableArrayList("snipdataevents") returns list.
I don't know whats wrong with the code...
Can anyone please help??
You can done this one by Passing ArrayList in form of String.
Add implementation 'com.google.code.gson:gson:2.8.4' in dependencies block build.gradle.
Click on Sync Project with Gradle Files
SnipDataEvents.java
public class SnipDataEvents {
private String title, image, language, bookingUrl, infoUrl, genre;
private List<Venues> venuesList;
public SnipDataEvents(String title, String image, String language, String genre, String bookingUrl, String infoUrl, List<Venues> list) {
venuesList = new ArrayList<>();
venuesList.addAll(list);
this.title = title;
this.image = image;
this.language = language;
this.genre = genre;
this.bookingUrl = bookingUrl;
this.infoUrl = infoUrl;
this.venuesList = list;
}
public String getImage() {
return image;
}
public String getTitle() {
return title;
}
public List<Venues> getVenuesList() {
return venuesList;
}
public void setVenuesList(List<Venues> venuesList) {
this.venuesList = venuesList;
}
public String getBookingUrl() {
return bookingUrl;
}
public String getGenre() {
return genre;
}
public String getInfoUrl() {
return infoUrl;
}
public String getLanguage() {
return language;
}
}
Venues.java
public class Venues {
private String name;
public Venues(String name, List<String> showTimes) {
this.name = name;
}
public String getName() {
return name;
}
}
MainActivity.java
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
Bundle bundle = new Bundle();
bundle.putExtra("snipdataevents", new Gson().toJson(snipDataEvents));
intent.putExtras(bundle);
startActivity(intent);
DetailActivity.java
String json = getIntent().getStringExtra("snipdataevents");
snipDataEvents = Arrays.asList(new Gson().fromJson(json, SnipDataEvents[].class))
I've one class, in which array list is there. How to send it through intent. following i did for my class
public class MakeOrder implements Parcelable {
#SerializedName("refno")
#Expose
private String refno;
#SerializedName("ddesc")
#Expose
private String ddesc;
#SerializedName("free")
#Expose
private String free;
#SerializedName("fgift")
#Expose
private String fgift;
#SerializedName("sgift")
#Expose
private String sgift;
#SerializedName("sandage")
#Expose
private SandageResponse sandage;
#SerializedName("inst")
#Expose
private String inst;
#SerializedName("items")
#Expose
private List<Item> items = new ArrayList<Item>();
#SerializedName("discount")
#Expose
private String discount;
#SerializedName("coupon")
#Expose
private Coupon coupon;
#SerializedName("delivery")
#Expose
private String delivery;
#SerializedName("user")
#Expose
private User user;
#SerializedName("otype")
#Expose
private String otype;
#SerializedName("ptype")
#Expose
private String ptype;
#SerializedName("app_id")
#Expose
private String appId;
#SerializedName("app_key")
#Expose
private String appKey;
#SerializedName("request")
#Expose
private String request;
#SerializedName("tablename")
#Expose
private String tablename;
#SerializedName("staff")
#Expose
private String staff;
public String getTablename() {
return tablename;
}
public void setTablename(String tablename) {
this.tablename = tablename;
}
public String getStaff() {
return staff;
}
public void setStaff(String staff) {
this.staff = staff;
}
public String getRefno() {
return refno;
}
public void setRefno(String refno) {
this.refno = refno;
}
public String getDdesc() {
return ddesc;
}
public void setDdesc(String ddesc) {
this.ddesc = ddesc;
}
public String getFree() {
return free;
}
public void setFree(String free) {
this.free = free;
}
public String getFgift() {
return fgift;
}
public void setFgift(String fgift) {
this.fgift = fgift;
}
public String getSgift() {
return sgift;
}
public void setSgift(String sgift) {
this.sgift = sgift;
}
public SandageResponse getSandage() {
return sandage;
}
public void setSandage(SandageResponse sandage) {
this.sandage = sandage;
}
public String getInst() {
return inst;
}
public void setInst(String inst) {
this.inst = inst;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public String getDiscount() {
return discount;
}
public void setDiscount(String discount) {
this.discount = discount;
}
public Coupon getCoupon() {
return coupon;
}
public void setCoupon(Coupon coupon) {
this.coupon = coupon;
}
public String getDelivery() {
return delivery;
}
public void setDelivery(String delivery) {
this.delivery = delivery;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getOtype() {
return otype;
}
public void setOtype(String otype) {
this.otype = otype;
}
public String getPtype() {
return ptype;
}
public void setPtype(String ptype) {
this.ptype = ptype;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getRequest() {
return request;
}
public void setRequest(String request) {
this.request = request;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.refno);
dest.writeString(this.ddesc);
dest.writeString(this.free);
dest.writeString(this.fgift);
dest.writeString(this.sgift);
dest.writeParcelable(this.sandage, flags);
dest.writeString(this.inst);
dest.writeTypedList(this.items);
dest.writeString(this.discount);
dest.writeParcelable(this.coupon, flags);
dest.writeString(this.delivery);
dest.writeParcelable(this.user, flags);
dest.writeString(this.otype);
dest.writeString(this.ptype);
dest.writeString(this.appId);
dest.writeString(this.appKey);
dest.writeString(this.request);
dest.writeString(this.tablename);
dest.writeString(this.staff);
}
public MakeOrder() {
}
protected MakeOrder(Parcel in) {
this.refno = in.readString();
this.ddesc = in.readString();
this.free = in.readString();
this.fgift = in.readString();
this.sgift = in.readString();
this.sandage = in.readParcelable(SandageResponse.class.getClassLoader());
this.inst = in.readString();
this.items = in.createTypedArrayList(Item.CREATOR);
this.discount = in.readString();
this.coupon = in.readParcelable(Coupon.class.getClassLoader());
this.delivery = in.readString();
this.user = in.readParcelable(User.class.getClassLoader());
this.otype = in.readString();
this.ptype = in.readString();
this.appId = in.readString();
this.appKey = in.readString();
this.request = in.readString();
this.tablename = in.readString();
this.staff = in.readString();
}
public static final Parcelable.Creator<MakeOrder> CREATOR = new Parcelable.Creator<MakeOrder>() {
#Override
public MakeOrder createFromParcel(Parcel source) {
return new MakeOrder(source);
}
#Override
public MakeOrder[] newArray(int size) {
return new MakeOrder[size];
}
};
}
Please take a look of updated one
I'm getting error like unable to marshal value
I made all class Parcelable. how to send its object through Intent
Thanks in Advance
Logcat is like
java.lang.RuntimeException: Parcel: unable to marshal value Models.PlaceOrder.Sub#41e10f80
at android.os.Parcel.writeValue(Parcel.java:1235)
at android.os.Parcel.writeList(Parcel.java:622)
at Models.PlaceOrder.Item.writeToParcel(Item.java:90)
at android.os.Parcel.writeTypedList(Parcel.java:1017)
at Models.PlaceOrder.MakeOrder.writeToParcel(MakeOrder.java:246)
at android.os.Parcel.writeParcelable(Parcel.java:1254)
at android.os.Parcel.writeValue(Parcel.java:1173)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1627)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.content.Intent.writeToParcel(Intent.java:6866)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:1897)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1418)
at android.app.Activity.internalStartActivityForResult(Activity.java:3427)
at android.app.Activity.access$200(Activity.java:660)
at android.app.Activity$2.onStartActivity(Activity.java:3417)
at android.app.Activity.startActivityForBusiness(Activity.java:5441)
at android.app.Activity.startActivityForResult(Activity.java:3413)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:75)
at android.app.Activity.startActivityForResult(Activity.java:3367)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:871)
at android.app.Activity.startActivity(Activity.java:3644)
at android.app.Activity.startActivity(Activity.java:3612)
Items.java where getting Exception
public class Item implements Parcelable {
#SerializedName("itemid")
#Expose
private String itemid;
#SerializedName("qty")
#Expose
private String qty;
#SerializedName("sub")
#Expose
private List<Sub> sub = new ArrayList<Sub>();
/**
*
* #return
* The itemid
*/
public String getItemid() {
return itemid;
}
/**
*
* #param itemid
* The itemid
*/
public void setItemid(String itemid) {
this.itemid = itemid;
}
/**
*
* #return
* The qty
*/
public String getQty() {
return qty;
}
/**
*
* #param qty
* The qty
*/
public void setQty(String qty) {
this.qty = qty;
}
/**
*
* #return
* The sub
*/
public List<Sub> getSub() {
return sub;
}
/**
*
* #param sub
* The sub
*/
public void setSub(List<Sub> sub) {
this.sub = sub;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.itemid);
dest.writeString(this.qty);
dest.writeList(this.sub);
}
public Item() {
}
protected Item(Parcel in) {
this.itemid = in.readString();
this.qty = in.readString();
this.sub = new ArrayList<Sub>();
in.readList(this.sub, Sub.class.getClassLoader());
}
public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>() {
#Override
public Item createFromParcel(Parcel source) {
return new Item(source);
}
#Override
public Item[] newArray(int size) {
return new Item[size];
}
};
}
You need to implement Parcelable also in the Item and Coupon objects.
Then when you add and read the list in you MakeOrder class:
#Override
public void writeToParcel(Parcel dest, int flags) {
...
// to write the Item list
dest.writeList(items);
// to write Coupon object
dest.writeParcelable(coupon, falgs);
}
BTW, your constructor is empty
private MakeOrder(Parcel in) {
...
// to read the Item list
items = new ArrayList<Item>();
in.readList(items, Item.CREATOR);
// to read Coupon object
in.readParcelable(Coupon.CREATOR);
}
This link could help you:
How to make a class with nested objects Parcelable
And this is the Parcelable documentation:
https://developer.android.com/reference/android/os/Parcel.html
EDIT:
The where more Percel problem added to the question.
Final solution in chat: https://chat.stackoverflow.com/rooms/123710/discussion-between-aman-singh-and-adalpari
You need to put in extras like this:
Intent intent-new Intent(this,YouActvity.class);
intent.putExtra("key",yourModel);
startActivity(intent);
In Activity to retrive:
YouModel yourModel = (YourModel) getIntent().getSerializableExtra("key");
Firstly, your Parcelable constructor is empty. If you leave it empty, then it won't work. You need to read fields from parcel the same order you wrote them in writeToParcel() method.
Then to write parcelable data to intent, putExtra() method of the intent. To extract data from intent, use getParcelableExtra() method of the intent
Try using this
intent.putParcelableArrayListExtra("value", orderList);
And in other Activity get it as:
List<String> orderList=this.getIntent().
getParcelableArrayListExtra("value");
Hope this helps
In my Android app, I want to use Intent to pass a list of SingleGroup to another Activity where each SingleGroup object contains a list of SingleImage, here are class for SingleImage and SingleGroup:
public class SingleImage implements Parcelable{
public String name;
public int drawableId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDrawableId() {
return drawableId;
}
public void setDrawableId(int drawableId) {
this.drawableId = drawableId;
}
public SingleImage(String name, int drawableId)
{
this.name = name;
this.drawableId = drawableId;
}
public static final Parcelable.Creator<SingleImage> CREATOR
= new Parcelable.Creator<SingleImage>()
{
public SingleImage createFromParcel(Parcel in)
{
return new SingleImage(in);
}
public SingleImage[] newArray(int size)
{
return new SingleImage[size];
}
};
private SingleImage(Parcel in)
{
name = in.readString();
drawableId = in.readInt();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(drawableId);
}
}
Here is SingleGroup class:
public class SingleGroup implements Parcelable{
private static final String TAG = "SINGLEGROUP";
private ArrayList<SingleImage> images = new ArrayList<SingleImage>(0);
private String myTitle;
private String groupDesc;
public SingleGroup(String mTitle, String desc, ArrayList<SingleImage> imagesList) {
this.myTitle = mTitle;
this.groupDesc = desc;
this.images = imagesList;
}
public String getGroupDesc() {
return groupDesc;
}
public String getMyTitle() {
return myTitle;
}
public void setMyTitle(String myTitle) {
this.myTitle = myTitle;
}
public ArrayList<SingleImage> getImages() {
return images;
}
public void setImages(ArrayList<SingleImage> images) {
this.images = images;
}
public static final Parcelable.Creator<SingleGroup> CREATOR
= new Parcelable.Creator<SingleGroup>()
{
public SingleGroup createFromParcel(Parcel in)
{
return new SingleGroup(in);
}
public SingleGroup[] newArray(int size)
{
return new SingleGroup[size];
}
};
private SingleGroup(Parcel in)
{
myTitle = in.readString();
groupDesc = in.readString();
//problem maybe here
in.readTypedList(images,SingleImage.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(myTitle);
dest.writeString(groupDesc);
//problem maybe here
dest.writeTypedList(images);
}
#Override
public String toString() {
String result = "myTitle "+myTitle+" desc "+ groupDesc + " imagesize "+images.size();
return result;
}
}
It works ok when calling to pass ArrayList<SingleImage> through Intent,
while when I called to pass ArrayLlist<SingleGroup> through Intent I got error:
Parcel android.os.Parcel#3c4c6743: Unmarshalling unknown type code
3211379 at offset 224
Any idea? Thanks in advance
---------------- Update ----------------
I have changed in.readTypedList(images, null); to in.readTypedList(images, SingleImage.CREATOR); but it still not working. same unmarshalling error
---------------- Problem Solved --------------
Thanks to Keita. The real problem is not actually listed in my code. When I passing the parcelable object, I should also include some other attributes which I missed.
Strongly recommend AS plugin Android Parcelable code generator
You must be pass SingleImage.CREATOR into method readTypedList instead of "null" value
private SingleGroup(Parcel in)
{
myTitle = in.readString();
groupDesc = in.readString();
//problem maybe here
in.readTypedList(images, SingleImage.CREATOR);
}
Try this one. That is what i always do and it work:
private SingleGroup(Parcel in)
{
myTitle = in.readString();
groupDesc = in.readString();
//problem maybe here
in.createTypedArrayList(SingleImage.CREATOR);
}
ArrayList is serialize. So try to this
public class SingleImage implements Serializable{
....
}
Refer this: ArrayList Android Documentation
I try to pass a News class to an activity, so I implemented the Parcelable interface. Inside News I have two classes implementing Parcelable too, Image and Date
The matter is that my News object at the end contains null for fields image and date.
Here my code:
News.java
public class News implements Parcelable {
public static final String TAG = "model_news";
private JSONObject object;
private int id;
private String type;
private String title;
private Boolean comment_disabled;
private String category_name;
private String url;
private Image images;
private Date date;
private Boolean is_video;
public News(JSONObject object) {
this.object = object;
try {
id = Integer.parseInt(object.getString("id"));
type = object.getString("type");
title = object.getString("title");
comment_disabled = object.getBoolean("comment_disabled");
category_name = object.getString("category_name");
url = object.getString("url");
if (!object.isNull("images")) {
images = new Image(object.getJSONObject("images"));
}
date = new Date(object.getJSONObject("date"));
is_video = object.getBoolean("is_video");
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
protected News(Parcel in) {
id = in.readInt();
type = in.readString();
title = in.readString();
category_name = in.readString();
url = in.readString();
images = (Image) in.readParcelable(Image.class.getClassLoader());
date = (Date) in.readParcelable(Date.class.getClassLoader());
is_video = in.readByte() != 0;
comment_disabled = in.readByte() != 0;
}
public static final Creator<News> CREATOR = new Creator<News>() {
#Override
public News createFromParcel(Parcel in) {
return new News(in);
}
#Override
public News[] newArray(int size) {
return new News[size];
}
};
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(type);
dest.writeString(title);
dest.writeByte((byte) (comment_disabled ? 1 : 0));
dest.writeString(category_name);
dest.writeString(url);
dest.writeParcelable(images, flags);
dest.writeParcelable(date, flags);
dest.writeByte((byte) (is_video ? 1 : 0));
}
#Override
public int describeContents() {
return 0;
}
}
Image.java
public class Image implements Parcelable {
public static final String TAG = "model_image";
private JSONObject imageObj;
private JSONObject original;
private String source;
private int width;
private Drawable image;
public Image(JSONObject imageObj) {
this.imageObj = imageObj;
try {
original = this.imageObj.getJSONObject("original");
source = original.getString("src");
width = original.getInt("width");
} catch (JSONException e) {
e.getMessage();
}
}
protected Image(Parcel in) {
source = in.readString();
width = in.readInt();
}
public static final Creator<Image> CREATOR = new Creator<Image>() {
#Override
public Image createFromParcel(Parcel in) {
return new Image(in);
}
#Override
public Image[] newArray(int size) {
return new Image[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(source);
dest.writeInt(width);
}
}
what I'm doing wrong ?
There is mistake in the Parcelable implementation.
First of all parcelable implementation states that: the fields passed in News(Parcel in) Constructor should be written in the same sequence in writeToParcel() method. Thats called Marshalling and Unmarshalling.
Corrections:
Drawable cannot be passed a parameter in Parcelable.
News Parcelable implementation.
Missed some of the fields its just for your understanding.
public class News implements Parcelable {
public static final String TAG = "model_news";
private JSONObject object;
private int id;
private String type;
private String title;
private Boolean comment_disabled;
private String category_name;
private String url;
private Image images;
private Date date;
private Boolean is_video;
protected News(Parcel in) {
id = in.readInt();
type = in.readString();
title = in.readString();
category_name = in.readString();
url = in.readString();
}
public static final Creator<News> CREATOR = new Creator<News>() {
#Override
public News createFromParcel(Parcel in) {
return new News(in);
}
#Override
public News[] newArray(int size) {
return new News[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(type);
dest.writeString(title);
dest.writeString(category_name);
dest.writeString(url);
}
}
public class Image implements Parcelable {
public static final String TAG = "model_image";
private JSONObject imageObj;
private JSONObject original;
private String source;
private int width;
private Drawable image;
protected Image(Parcel in) {
source = in.readString();
width = in.readInt();
}
public static final Creator<Image> CREATOR = new Creator<Image>() {
#Override
public Image createFromParcel(Parcel in) {
return new Image(in);
}
#Override
public Image[] newArray(int size) {
return new Image[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(source);
dest.writeInt(width);
}
}