I'd like to make class A Parcelable.
public class A {
public String str;
public ArrayList<B> list;
}
This is what I've come up with so far. However it crashes with a NullPointerException. The problem are these two statements: dest.writeList(list);
& in.readList(list, this.getClass().getClassLoader());
.
I can't figure out what to do from here :(
Class A
public class A implements Parcelable {
public String str;
public ArrayList<B> list;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
dest.writeList(list);
}
private A(Parcel in) {
str = in.readString();
in.readList(list, this.getClass().getClassLoader());
}
public static final Parcelable.Creator<A> CREATOR
= new Parcelable.Creator<A>() {
public A createFromParcel(Parcel in) {
return new A(in);
}
public A[] newArray(int size) {
return new A[size];
}
};
}
Class B
public class B implements Parcelable {
public String str;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
}
private B(Parcel in) {
str = in.readString();
}
public static final Parcelable.Creator<B> CREATOR
= new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
}
Thank you for your time.
I finally figured out what to type into Google :), and found this Android, How to use readTypedList method correctly in a Parcelable class?
The solution was to use read-/writeTypedList
instead. I also initialize the arraylist to avoid any further NullPointerException.
Class A
public class A implements Parcelable {
public String str;
public ArrayList<B> list = new ArrayList<B>();
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
dest.writeTypedList(list);
}
private A(Parcel in) {
str = in.readString();
in.readTypedList(list, B.CREATOR);
}
public static final Parcelable.Creator<A> CREATOR
= new Parcelable.Creator<A>() {
public A createFromParcel(Parcel in) {
return new A(in);
}
public A[] newArray(int size) {
return new A[size];
}
};
}
Class B
public class B implements Parcelable {
public String str;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
}
private B(Parcel in) {
str = in.readString();
}
public static final Parcelable.Creator<B> CREATOR
= new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
}
If you have only one Parcelable
object inside your main Parcelable
object, not list like the accepted answer case. Then it will be like the following:
Class A
public class A implements Parcelable {
public String str;
public B objectB;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
//The parcelable object has to be the first one
dest.writeParcelable(objectB, flags);
dest.writeString(str);
}
private A(Parcel in) {
this.objectB = in.readParcelable(B.class.getClassLoader());
str = in.readString();
}
public static final Parcelable.Creator<A> CREATOR
= new Parcelable.Creator<A>() {
public A createFromParcel(Parcel in) {
return new A(in);
}
public A[] newArray(int size) {
return new A[size];
}
};
}
Class B
public class B implements Parcelable {
public String str;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
}
private B(Parcel in) {
str = in.readString();
}
public static final Parcelable.Creator<B> CREATOR
= new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
}
IMPORTANT:
Please note that the order that you write and read the Parcelable
object matters. Checkout this answer for more details
At Write to parcel
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name); //if String
parcel.writeTypedList(assignedEmployees); //if List with custom class, eg. List<AssignedEmployee> assignedEmployees
parcel.writeParcelable(checkin,i); //if custom class, eg. Checkin checkin;
}
At Constructor for reading it back
protected A(Parcel in) {
name = in.readString();
assignedEmployees = in.createTypedArrayList(AssignedEmployee.CREATOR);
checkin = in.readParcelable(Checkin.class.getClassLoader());
}
where AssignedEmployee, Checkin where custom classes and it should implement Parcelable.
Just press ALT+ENTER and replace Parcelable it will implement all the necessary implementation
You can add the Parcelable code generator plugin from prefs, from there you can create the parcelable boiler plate code by doing: - right click class name within model - select generate - select Parcelable
presto - your model will be updated with necessary Parcelable boilerplate code.
I had the same problem here's a generic version
class Item<T : Parcelable> (val model: T, val index: Int ) : Parcelable {
constructor(parcel: Parcel) :
this(parcel.readParcelable(
Item<T>::model.javaClass.classLoader),
parcel.readInt()
) {}
override fun writeToParcel(parcel: Parcel?, flag: Int) {
parcel?.writeParcelable(model, 0)
parcel?.writeInt(index)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Item<Parcelable>> {
override fun createFromParcel(parcel: Parcel): Item<Parcelable> {
return Item(parcel)
}
override fun newArray(size: Int): Array<Item<Parcelable>?> {
return arrayOfNulls(size)
}
}
}
I was unfortunately using a class (BarEntry
) from a 3rd party library which was not able to be parceled. I solved my problem by passing through Intent
an array of float
s and then reconstructing my BarEntry
objects at the receiving end.
This is sub-optimal but it can be a useful process if anyone has a similar circumstance where creating a parcel able object is not an option.
来源:https://stackoverflow.com/questions/14178736/how-to-make-a-class-with-nested-objects-parcelable