如何使用数组列表正确实现 Parcelable < Parcelable > ?

我在上 Parcelable课时遇到了麻烦。麻烦的是,我正在尝试写一个类中的一个成员到包中,它是一个 ArrayList<Parcelable>对象。ArrayListSerializable,列表中的对象(ZigBeeDev)是 Parcelable

以下是相关代码:

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];
}
};


//...
}

我已经标记了两个点“//帮助这里”,以了解如何正确地写包裹和如何重建它。如果 ZigBeeDevParcelable(正确测试) ,我如何正确地做到这一点?

57471 次浏览

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.

You should use writeList(List l) for your list of integers and writeTypedList(List val) for the list of ZigBeeDevices

In my case in.readTypedList(_devices, ZigBeeDev.CREATOR); gave me a NullPointerException on _devices. So I used this:

_devices = in.createTypedArrayList(ZigBeeDev.CREATOR);

In constructor you should use

_lqis = in.createTypedArrayList(ZigBeeDev.CREATOR);

And in "writeToParcel" use

out.writeTypedList(_lqis);

A little late but I also had this issue. After a long waste of time I stumbled upon the parcelabler.com website which automatically creates parcels for you.

It allowed me to create a nested parcel with an array list inside very easily, and saved me a lot of time.

Basically the way the website works is you enter your object with the ArrayList in it and it automatically adds the necessary methods to make it parcelable (read from parcel, write to parcel, describe contents, and parcel Creator are all generated automatically). This is particularily useful when creating complex parcels, such as the question here asks, which contain nested parcels, arrays, and lists.

EDIT: Also IntelliJ IDEA and Android Studio have plugins for this which do a similar thing to the website listed:

These plugins generate Android Parcelable boilerplate code based on fields in the class.