I'm facing a problem when passing a list of parcelable objects to the intent of one new activity.
Here's what I do:
Intent intent = new Intent(context, CurriculumCorsesActivity.class);
intent.setExtrasClassLoader(CurriculumCourseCard.class.getClassLoader());
intent.putParcelableArrayListExtra("courses", card.getCourses());
context.startActivity(intent);
And when I call the startActivity I get the following error:
E/Parcel﹕ Class not found when unmarshalling: pt.tecnico.fenixmobile.person.CurriculumCourseCard, e: java.lang.ClassNotFoundException: pt.tecnico.fenixmobile.person.CurriculumCourseCard
CurriculumCourseCard implements the Parcelable interface. Here's is the implementation:
public class CurriculumCourseCard implements Serializable, Parcelable{
private static final long serialVersionUID = 765578940083L;
private String courseName;
private String finalGrade;
private String ects;
public CurriculumCourseCard(Parcel in) {
this.courseName = in.readString();
this.finalGrade = in.readString();
this.ects = in.readString();
}
public String getCourseName() {
return courseName;
}
public String getFinalGrade() {
return finalGrade;
}
public String getEcts() {
return ects;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(this.courseName);
parcel.writeString(this.finalGrade);
parcel.writeString(this.ects);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public CurriculumCourseCard createFromParcel(Parcel in) {
return new CurriculumCourseCard(in);
}
public CurriculumCourseCard[] newArray(int size) {
return new CurriculumCourseCard[size];
}
};}
And this is how I'm getting the list in the new activity:
Intent intent = getIntent();
intent.setExtrasClassLoader(CurriculumCourseCard.class.getClassLoader());
ArrayList<CurriculumCourseCard> courses = intent.getParcelableArrayListExtra("courses");
In the new activity I see as much items as there are in the list, but no content at all. And the only error is the one described before.
Hope you can help me.
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've a custom parcelable (simplified) that contains a string array:
public class MyClass implements Parcelable {
public static final Creator<MyClass> CREATOR = new Creator<MyClass>() {
public MyClass createFromParcel(Parcel in) {
return new MyClass(in);
}
public MyClass[] newArray(int size) {
return new MyClass[size];
}
};
#SerializedName(“tips”)
private List<String> Tips;
public MyClass() {
Tips = new ArrayList<>();
}
protected Category(Parcel in) {
Tips = in.createStringArrayList();
}
public List<String> getTips() {
return Tips;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(Tips);
}
}
I'm trying to pass this parcelable via Intent to another activity. The process is VERY slow and sometimes I get an OOM exception...I don't understand why, I just want to pass a string array...
Save your array into database and pass id of that record.
in an activity from my app I have an Intent to start a new Activity and I want to pass an ArrayList i.e. an ArrayList where each item is an instance of a own class ... how can I make this?
I have been seeing possible getExtras() like getStringArrayList() or getParcelableArrayList() and it doesn't work, I haven't found any valid type.
Can anyone help me? Thanks.
This is my class:
public class ItemFile {
protected long id;
protected String nombre;
protected String rutaImagen;
protected boolean checked;
public ItemFile(long id, String nombre, String rutaImagen, boolean check) {
this.id = id;
this.nombre = nombre;
this.rutaImagen = rutaImagen;
this.checked = check;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getRutaImagen() {
return rutaImagen;
}
public void setRutaImagen(String rutaImagen) {
this.rutaImagen = rutaImagen;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked){
this.checked = checked;
}
}
How I must change it to set Parcelable?
First make sure MyClass class implements Parcelable interface then use this code for getting ArrayList in other Activity :
In your first activity do something like this:
ArrayList<MyClass> myClassList= new ArrayList<MyClass>();
Intent intent = new Intent(<YOUR ACTIVITY CONTEX>, <NEXT ACTIVITY>);
intent.putExtra("myClassList", myClassList);
startActivity(intent);
In your next activity do something like this:
ArrayList<MyClass> list = (ArrayList<MyClass>)getIntent().getExtras()getSerializable("myClassList");
Make MyClass Parcelable. See example below.
public class MyClass implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
// Send it using
ArrayList<MyClass> list;
intent.putParcelableArrayListExtra("list", list);
In First activity
ArrayList<MyClass> fileList = new ArrayList<MyClass>();
Intent intent = new Intent(MainActivity.this, secondActivity.class);
intent.putExtra("FILES_TO_SEND", fileList);
startActivity(intent);
In Secand
activity:ArrayList<MyClass> filelist =(ArrayList<MyClass>)getIntent().getSerializableExtra("FILES_TO_SEND");
I had been struggling with this myself but I found a fairly simple solution on tutorialspoint that worked well for me.
In the source activity, use
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("key", numbers);
startActivity(intent);
Then in the destination activity, use
ArrayList<String> numbersList = (ArrayList<String>) getIntent().getSerializableExtra("key");
A link to the full tutorial is: https://www.tutorialspoint.com/how-to-pass-an-arraylist-to-another-activity-using-intents-in-android
I'm having trouble passing an object via an Intent. I keep getting a null pointer error. here it is:
In my ListActivity:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(MyListActivity.this, DetailsActivity.class);
intent.putExtra("this_item", my_array.get(position));
startActivity(intent);
}
In the onCreate() of the DetailsActivity class:
thisItem = (MyObject) getIntent().getExtras().getParcelable("this_item");
System.err.println(thisItem.getDescription()); //<--Null pointer error!
The MyObject class does implement Parcelable. Why can't I pass this object over? I'm confused. Thanks for any help.
EDIT: Here is that class:
public class MyObject implements Comparable<MyObject>, Parcelable {
private Date date;
private MyType my_type;
private String description;
private int flags;
public MyObject(Date date, MyType type, String desc) {
this.date = date;
this.my_type = type;
this.description = desc;
}
public Date getDate() {return date;}
public MyType getMyType() {return my_type;}
public String getDescription() {return description;}
public int compareTo(MyObject another) {
if (getDate() == null || another.getDate() == null) {return 0;}
return getDate().compareTo(another.getDate());
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(flags);
}
public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
public MyObject createFromParcel(Parcel in) {
return new MyObject(in);
}
public MyObject[] newArray(int size) {
return new MyObject[size];
}
};
private MyObject (Parcel in) {
flags = in.readInt();
}
}
If you want to pass the data from one activity to another actiivty via intent the object must be parcelable or serializable in android..for parcelable you have to implement the serializable interface..for parcelable you must implement parcelable interface..
Write parcelable class like this..
parcel example
I have a class that contains data i want to pass it between intents, this class have arraylist that contains another class objects. this is my class
public class ParsedData implements Parcelable {
public String error;
public float protectionLevel;
public int protectionLevelColor;
public double lastBackup;
public boolean compressedType;
public Long driveFreeSpaceSize;
ArrayList<Item>Items = new ArrayList<Item>();
}
class Item {
public String name;
public float percentage;
public int files;
public long size;
}
how can i send this class between intents ?
you can let your class Item implements the Serializable interface, and use Intent.putExtra(String, Serializable). Since ArrayList implements also the Serializable interface, you can pass the whole Items object.
This may be your problem:
Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface.
Alternatively, I'd try to have Item implement Parcelable, as well.
The fail-safe alternative is to write your data structure into a JSON string, which also allows you to pass the data to other applications that don't have access to your ParsedData class.
You may take a look at Intent.putExtra(String name, Parcelable object) and implement the parcelable interface in your class.
i have found the answer after all. thanks all how helped me
this is the answer:
import android.os.Parcel;
import android.os.Parcelable;
public class ParsedData implements Parcelable {
public String error;
public float protectionLevel;
public int protectionLevelColor;
public double lastBackup;
public boolean compressedType;
public Long statusSendTime;
ArrayList<Item>Items = new ArrayList<Item>();
//---------------------Constructors---------------------------
public ParsedData() { ; };
public ParsedData(Parcel in) {
readFromParcel(in);
}
//------------------------------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(error);
dest.writeFloat(protectionLevel);
dest.writeInt(protectionLevelColor);
dest.writeDouble(lastBackup);
dest.writeByte((byte) (compressedType ? 1 : 0));
dest.writeLong(statusSendTime);
dest.writeList(Items);
}
private void readFromParcel(Parcel in) {
error = in.readString();
protectionLevel = in.readFloat();
protectionLevelColor = in.readInt();
lastBackup = in.readDouble();
compressedType =in.readByte() == 1;
statusSendTime = in.readLong();
in.readList(Items,Item.class.getClassLoader() );
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ParsedData createFromParcel(Parcel in) {
return new ParsedData(in);
}
public ParsedData[] newArray(int size) {
return new ParsedData[size];
}
};
}
class Item implements Parcelable {
public String name;
public float percentage;
//---------------------Constructors---------------------------
public Item() {
}
public Item(Parcel in) {
readFromParcel(in);
}
//------------------------------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeFloat(percentage);
}
public static final Creator<Item> CREATOR = new Creator<Item>() {
public Item createFromParcel(Parcel source) {
return new Item(source);
}
public Item[] newArray(int size) {
return new Item[size];
}
};
private void readFromParcel(Parcel in) {
this.name = in.readString();
this.percentage = in.readFloat();
}
}
and in the caller activity
ParsedData data = new PArsedData();
Intent intentBreakDown = new Intent(this,BreakDownBarActivity.class);
intentBreakDown.putExtra("data", data);
startActivity(intentBreakDown);
in the called activity(BreakDownBarActivity in my case)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.breakdownbar);
Bundle b = getIntent().getExtras();
ParsedData data = (ParsedData)b.getParcelable("data");
}