I must send an Object value to other Activity, so I found the way to using Parcelable Object. but this is the problem.
The problem is not parcelable object can not be add Parcelable object.
import android.os.Parcel;
import android.os.Parcelable;
import org.apache.http.Header;
import java.util.ArrayList;
public class CustomParcelable implements Parcelable {
// Extra Header
private ArrayList<Header> headers = new ArrayList<Header>();
public CustomParcelable() {}
public CustomParcelable(ArrayList<Header> headers) {
this.headers = headers;
}
// getter and setter
// ...
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(headers);
}
public static final Creator<CustomParcelable> CREATOR = new Creator<CustomParcelable>() {
#Override
public CustomParcelable createFromParcel(Parcel source) {
ArrayList<Header> headers = new ArrayList<Header>();
source.readList(headers, null);
return new CustomParcelable( headers);
}
#Override
public CustomParcelable[] newArray(int size) {
return new CustomParcelable[size];
}
};
}
this code has exception like this.
IllegalArgumentException("Parcel: unknown type for value " + v);
Is anything missing on this?
thank you.
Its should be
#Override
public CustomParcelable createFromParcel(Parcel source) {
ArrayList<Header> headers = new ArrayList<Header>();
source.readList("key", headers );
return new CustomParcelable( source);
}
Related
Reaching to ask for your help on this one.
I'm getting the error:
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = java.util.ArrayList)
I'm already implementing Parcelable both in the Entities class (which is an ArrayList of Entity) as in the Entity class.
The code for the Entities class is as follows:
package my.package;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
public class Entities implements Parcelable {
private ArrayList<Entity> entities = new ArrayList<>();
public Entities() {
}
public ArrayList<Entity> getEntities() {
return entities;
}
public void setEntities(ArrayList<Entity> entities) {
this.entities = entities;
}
// Parcelable
private Entities(Parcel in) {
entities = (ArrayList<Entity>) in.readSerializable();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(entities);
}
public static final Parcelable.Creator<Entities> CREATOR = new Parcelable.Creator<Entities>() {
#Override
public Entities createFromParcel(Parcel parcel) {
return new Entities(parcel);
}
#Override
public Entities[] newArray(int i) {
return new Entities[i];
}
};
}
And to move into the next Activity I'm doing so:
ArrayList<Entity> entities = new ArrayList<Entity>();
Entities entities_ = new Entities();
for (int i = 0; i < jsonArray_Entities.length(); i++) {
JSONObject jsonObject_Entity = jsonArray_Entities.getJSONObject(i);
Entity entity = new Entity();
(Here goes all the entity.set() logic)
entities.add(entity);
}
entities_.setEntities(entities);
if (entities.size() > 0) {
Intent intent = new Intent(SearchEntitiesActivity.this, ListEntitiesActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("entities", entities_);
intent.putExtras(bundle);
startActivity(intent);
}
Can you identify what I'm doing wrong?
Thanks in advance.
For ArrayList, I recommend writeParcelableList() instead of writeSerializable(), and readArrayList() instead of readSerializable().
Of course, really I recommend Kotlin and #Parcelize, where all this stuff gets nicely code-generated for you! 😀
Hey guys ive found some tutorials about sending non primitive object to activity via intent. But see only that they have members of only primitive in all examples.
I have a class with members that are user data types.
How do i send an object with implementing Parcelable with non primitive instance variables like arraylist etc?
Thanks
The objects that are members of your class must also be Parcelable (or Serializable), and any objects they include must also be Parcelable (or Serializable). To summarize, a Parcelable object must have fields that are either: primitives, Parcelable objects (and their supported collections such as Map or ArrayList) or Serializable objects(and their supported collections such as Map or ArrayList).
A sample piece of code demonstrating this (the Foo class is a Parcelable which contains Bar, which is also Parcelable), is the following (in Java):
import android.os.Parcel;
import android.os.Parcelable;
public class Foo implements Parcelable {
private int primitive;
private Bar object;
public Foo() {
primitive = 0;
object = null;
}
private Foo(final Parcel in) {
primitive = in.readInt();
object = in.readParcelable(Bar.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(primitive);
dest.writeParcelable(object, flags);
}
public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>() {
public Foo createFromParcel(Parcel in) {
return new Foo(in);
}
public Foo[] newArray(int size) {
return new Foo[size];
}
};
}
and the Bar class:
import android.os.Parcel;
import android.os.Parcelable;
public class Bar implements Parcelable {
private String attribute;
public Bar() {
attribute = "";
}
private Bar(final Parcel in) {
attribute = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(attribute);
}
public static final Parcelable.Creator<Bar> CREATOR = new Parcelable.Creator<Bar>() {
public Bar createFromParcel(Parcel in) {
return new Bar(in);
}
public Bar[] newArray(int size) {
return new Bar[size];
}
};
}
e.g
Class City that needs to implement Parcelable has field of type Location which implements Serializable. class Location is imported from a third party jar file and I cannot modify it. How do I successfully implement Parcelable for class City with the Location field ?
Simply use Parcel.writeSerializable() and Parcel.readSerializable()
public class MyParcelableObject implements Parcelable {
public static final Parcelable.Creator<MyParcelableObject> CREATOR =
new Parcelable.Creator<MyParcelableObject>() {
#Override
public MyParcelableObject createFromParcel(Parcel in) {
return new MyParcelableObject(in);
}
#Override
public MyParcelableObject[] newArray(int size) {
return new MyParcelableObject[size];
}
};
private final MySerializableObject mySerializableField;
private MyParcelableObject(Parcel in) {
this.mySerializableField = (MySerializableObject) in.readSerializable();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(mySerializableField);
}
#Override
public int describeContents() {
return 0;
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I'm trying to read a List of Strings and I keep having the following error:
with the following Parcelable class:
import java.util.List;
import android.os.Parcel;
import android.os.Parcelable;
public class ActivePolicies implements Parcelable {
private List<String> activePolicies;
public ActivePolicies(List<String> activePolicies) {
this.activePolicies = activePolicies;
}
public List<String> getActivePolicies(){
return activePolicies;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(activePolicies);
}
public static final Parcelable.Creator<ActivePolicies> CREATOR = new Parcelable.Creator<ActivePolicies>() {
#Override
public ActivePolicies createFromParcel(Parcel in) {
try {
return new ActivePolicies(in.createStringArrayList());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
public ActivePolicies[] newArray(int size) {
return new ActivePolicies[size];
}
};
}
It keeps giving me the exception on createFromParcel(), but I can't figure out why.
It seems a simple parcelable, but when I'm debugging at readStringList() from the Parcel class, the list is null.
But when I evaluate the value in createStringArrayList() before it's returning, the list is there with the expected values.
you need to create constructor that accept Parcel
public ActivePolicies(Parcel in) {
in.readStringList(activePolicies);
}
in.createStringArrayList()? Why are you creating a new String list when you want to construct your object?
Use this method.
Parcel.readStringList(List<String> list)
Read into the given List items String objects that were written with
writeStringList(List) at the current dataPosition().
Recommended: implement a constructor that accepts a Parcel, then, optionally a readFromParcel method.
public class ActivePolicies implements Parcelable {
private List<String> activePolicies;
public ActivePolicies() {
activePolicies = new ArrayList<String>();
}
public ActivePolicies(Parcel in) {
this();
readFromParcel(in);
}
private void readFromParcel(Parcel in) {
in.readStringList(activePolicies);
}
In the creator.
return new ActivePolicies(in);
To pass an arrayList of objects to a fragment, I have to make the list objects parcelable.
public mObjectClass implements Parcelable {
// Some code
}
The problem is that one of the attributes in my list objects is another object-based arrayList.
public mObjectClass implements Parcelable {
// Some code
private ArrayList<someOtherObject> anotherArrayList;
}
How can I make mObjectClass parcelable?
someOtherObject has to implement Parcelable (not extend has in your question) too. Then you can call parcel.writeTypedList(anotherArrayList); to write it and parcel.readTypedList(yourList, someOtherObject.CREATOR) to read it back. You can read more here
This solution is heavily influenced by some Stackoverflow posts, including
this.
Essentially make both Classes parcelable and make use of someOtherClasses Parcelable.Creator.
mObjectClass:
public class mObjectClass implements Parcelable {
private ArrayList<someOtherObject> anotherArrayList;
//add getter + setter...
public mObjectClass() {
anotherArrayList = new ArrayList<someOtherObject>();
}
public mObjectClass(Parcel in) {
anotherArrayList = new ArrayList<someOtherObject>();
in.readTypedList(anotherArrayList, someOtherObject.CREATOR);
}
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel outParcel, int flags) {
outParcel.writeTypedList(anotherArrayList);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
#Override
public mObjectClass createFromParcel(Parcel in) {
return new mObjectClass(in);
}
#Override
public mObjectClass[] newArray(int size) {
return new mObjectClass[size];
}
};
}
someOtherObject:
public class someOtherObject implements Parcelable {
String someString;
//add getter + setter...
public void writeToParcel(Parcel out, int flags) {
out.writeString(someString);
}
public static final Parcelable.Creator<someOtherObject> CREATOR = new Parcelable.Creator<someOtherObject>() {
public someOtherObject createFromParcel(Parcel in) {
return new someOtherObject(in);
}
public someOtherObject[] newArray(int size) {
return new someOtherObject[size];
}
};
public int describeContents() {
return 0;
}
public someOtherObject(Parcel in) {
someString = in.readString();
}
public someOtherObject() {
}
public someOtherObject(String someString) {
this.someString = someString;
}
}
Tada, you are now able to add mObjectClass as extra to your intents after initialising it and using a setter to set the Arraylist with other someOtherObjects.