J'ai du mal à faire ma classe Parcelable
. Le problème est que j'essaie d'écrire au colis un membre de la classe qui est un ArrayList<Parcelable>
objet. ArrayList
est Serializable
et les objets (ZigBeeDev
) dans la liste sont Parcelable
.
Voici le code pertinent:
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];
}
};
//...
}
J'ai marqué deux points "// help here" pour comprendre comment écrire correctement sur le colis et comment le reconstruire. Si ZigBeeDev
est Parcelable
(correctement testé), comment dois-je procéder correctement?
Vous l'avez presque compris!
Il vous suffit de faire:
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);
}
C'est tout!
Pour votre liste d'Integer, vous pouvez également faire:
out.writeList(_lqis);
_lqis = new ArrayList<>();
in.readList(_lqis Integer.class.getClassLoader());
Ça devrait marcher.
Dans mon cas, in.readTypedList(_devices, ZigBeeDev.CREATOR);
m'a donné un NullPointerException
sur _devices
. J'ai donc utilisé ceci:
_devices = in.createTypedArrayList(ZigBeeDev.CREATOR);
Vous devez utiliser writeList (List l) pour votre liste d'entiers et writeTypedList (List val) pour la liste de ZigBeeDevices
Dans constructeur, vous devez utiliser
_lqis = in.createTypedArrayList(ZigBeeDev.CREATOR);
Et dans l'utilisation de "writeToParcel"
out.writeTypedList(_lqis);
Un peu tard mais j'ai aussi eu ce problème. Après une longue perte de temps, je suis tombé sur le site parcelabler.com qui crée automatiquement des colis pour vous.
Cela m'a permis de créer très facilement une parcelle imbriquée contenant une liste de tableaux et m'a fait gagner beaucoup de temps.
Fondamentalement, le fonctionnement du site Web consiste à saisir votre objet avec la liste de tableaux et il ajoute automatiquement les méthodes nécessaires pour le rendre parcellable (lire à partir de parcelle, écrire sur parcelle, décrire le contenu et Créateur de parcelle sont tous générés automatiquement). Cela est particulièrement utile lors de la création de parcelles complexes, telles que la question posée ici, qui contiennent des parcelles, des tableaux et des listes imbriqués.
EDIT: Aussi IntelliJ IDEA et Android Studio a des plugins pour cela qui font une chose similaire au site Web répertorié:
Ces plugins génèrent Android Parcelable code passe-partout basé sur les champs de la classe.