76 votes

comment implémenter correctement Parcelable avec un ArrayList<Parcelable> ?

J'ai du mal à faire en sorte que ma classe Parcelable . Le problème est que j'essaie d'écrire dans le paquet un membre de la classe qui est une ArrayList<Parcelable> objet. Le site ArrayList es Serializable et les objets ( ZigBeeDev ) dans la liste sont Parcelable .

Voici le code correspondant :

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 endroits "// aide ici" pour comprendre comment écrire correctement au colis et comment le reconstruire. Si ZigBeeDev es Parcelable (correctement testé), comment faire correctement ?

142voto

NitroG42 Points 2421

Vous avez presque réussi !

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'entiers, vous pouvez aussi faire :

out.writeList(_lqis);
_lqis = new ArrayList<>();
in.readList(_lqis Integer.class.getClassLoader());

Cela devrait fonctionner.

17voto

osrl Points 4178

Dans mon cas in.readTypedList(_devices, ZigBeeDev.CREATOR); m'a donné un NullPointerException en _devices . J'ai donc utilisé ceci :

_devices = in.createTypedArrayList(ZigBeeDev.CREATOR);

8voto

DoubleMalt Points 720

Vous devez utiliser writeList(Liste l) pour votre liste d'entiers et writeTypedList(Liste val) pour la liste des ZigBeeDevices

2voto

Anton Smirnov Points 89

Dans le constructeur, vous devez utiliser

_lqis = in.createTypedArrayList(ZigBeeDev.CREATOR);

Et dans "writeToParcel", utilisez

out.writeTypedList(_lqis);

0voto

JFreeman Points 472

Un peu tard mais j'ai aussi eu ce problème. Après une longue perte de temps, je suis tombé sur la parcelabler.com qui crée automatiquement des colis pour vous.

Il m'a permis de créer très facilement un paquet imbriqué avec une liste de tableaux à l'intérieur, et m'a fait gagner beaucoup de temps.

En gros, le site Web fonctionne de la manière suivante : vous entrez votre objet contenant la liste de tableaux et il ajoute automatiquement les méthodes nécessaires pour le rendre "parcelable" (read from parcel, write to parcel, describe contents, and parcel Creator are all generated automatically). Ceci est particulièrement utile lors de la création de paquets complexes, comme la question posée ici, qui contiennent des paquets, des tableaux et des listes imbriqués.

EDIT : Aussi IntelliJ IDEA et Android Studio ont des plugins pour cela qui font une chose similaire au site web indiqué :

Ces plugins génèrent Android Parcelable code passe-partout basé sur les champs de la classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X