how to properly implement Parcelable with an ArrayList<Parcelable>?
Solution 1
You almost got it !
You just need to do :
public void writeToParcel(Parcel out, int flags) {
out.writeString(_mac);
out.writeString(_pan);
out.writeInt(_band);
out.writeSerializable(_lqis);
out.writeTypedList(_devices);
}
private ZigBeeNetwork(Parcel in) {
_mac = in.readString();
_pan = in.readString();
_band = in.readInt();
_lqis = (ArrayList<Integer>) in.readSerializable();
in.readTypedList(_devices, ZigBeeDev.CREATOR);
}
That's all!
For your list of Integer, you can also do :
out.writeList(_lqis);
_lqis = new ArrayList<>();
in.readList(_lqis Integer.class.getClassLoader());
It should work.
Solution 2
In my case in.readTypedList(_devices, ZigBeeDev.CREATOR);
gave me a NullPointerException
on _devices
. So I used this:
_devices = in.createTypedArrayList(ZigBeeDev.CREATOR);
Solution 3
You should use writeList(List l) for your list of integers and writeTypedList(List val) for the list of ZigBeeDevices
Solution 4
In constructor you should use
_lqis = in.createTypedArrayList(ZigBeeDev.CREATOR);
And in "writeToParcel" use
out.writeTypedList(_lqis);
Related videos on Youtube
Comments
-
gnychis almost 2 years
I am having trouble making my class
Parcelable
. The trouble is, I am trying to write to the parcel a member in the class which is anArrayList<Parcelable>
object. TheArrayList
isSerializable
, and the objects (ZigBeeDev
) in the list areParcelable
.Here is the relevant code:
package com.gnychis.coexisyst; import java.util.ArrayList; import java.util.Iterator; import android.os.Parcel; import android.os.Parcelable; public class ZigBeeNetwork implements Parcelable { public String _mac; // the source address (of the coordinator?) public String _pan; // the network address public int _band; // the channel ArrayList<Integer> _lqis; // link quality indicators (to all devices?) ArrayList<ZigBeeDev> _devices; // the devices in the network public void writeToParcel(Parcel out, int flags) { out.writeString(_mac); out.writeString(_pan); out.writeInt(_band); out.writeSerializable(_lqis); out.writeParcelable(_devices, 0); // help here } private ZigBeeNetwork(Parcel in) { _mac = in.readString(); _pan = in.readString(); _band = in.readInt(); _lqis = (ArrayList<Integer>) in.readSerializable(); _devices = in.readParcelable(ZigBeeDev.class.getClassLoader()); // help here } public int describeContents() { return this.hashCode(); } public static final Parcelable.Creator<ZigBeeNetwork> CREATOR = new Parcelable.Creator<ZigBeeNetwork>() { public ZigBeeNetwork createFromParcel(Parcel in) { return new ZigBeeNetwork(in); } public ZigBeeNetwork[] newArray(int size) { return new ZigBeeNetwork[size]; } }; //... }
I have marked two spots "// help here" to understand how to properly write to the parcel and how to reconstruct it. If
ZigBeeDev
isParcelable
(properly tested), how do I do this properly? -
gatlingxyz about 10 yearsFor future reference, and I'm not sure if it's a typo that no one has noticed, but
ZigBeeDev.Creator
should beZigBeeDev.CREATOR
. I got an error every time until I realized there were two different creators I could use in my own project. -
AlexAndro almost 10 years@NitroG42 The second approach for read list results into
cannot convert from void to ArrayList<Integer>
-
sgarman over 9 yearsI also needed to instantiate the array before as well, example my code would look like: _devices = new ArrayList<ZigBeeDev>(); in.readTypedList(_devices, ZigBeeDev.Creator);
-
rf43 over 8 yearsfwiw - the reason you were receiving a NPE is because if you use
in.readTypedList()
you need to create a new ArrayList() first and then pass that to thein.readTypedList(yourNewArrayList, YourObj.CREATOR)
otherwise it will only be trying to put the data into a null list. -
osrl over 8 yearsYes, that's correct. I've read the source code before I used it. Thank you for the extra information which I forgot to write.
-
Ajit Kumar Dubey over 8 years@osrl when we follow your solution got exception java.lang.OutOfMemoryError: Failed to allocate a 13893804 byte allocation with 11004100 free bytes and 10MB until OOM
-
osrl about 8 yearsDoes your array hold files or something big? @Ajit
-
crubio about 8 years@sgarman There's no need to instantiate the array cause then you get the warning: Explicit type argument ZigBeeDev can be replaced with <> This inspection reports all new expressions with type arguments which can be replaced with diamond type <>
-
Eido95 over 7 yearsConfirm to be working with generic
Hashtable
that uses primitives types (includingString
) for either of his keys or values.