Jean Jimenez
Jean Jimenez

Reputation: 4742

Android Parcelable Problem with array

Hi everybody i have build a class that implements Parcelable but one of the arraylist attributes i have define gets empty when i read the class. Here is the code

package roblestech.laCartelera;

import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;

public class ProgramacionPelicula implements Parcelable {

    public ProgramacionPelicula() {
    }

    public ProgramacionPelicula(Pelicula pelicula) {
        _pelicula = pelicula;
    }

    public ProgramacionPelicula(Cine cine) {
        _cine = cine;
    }

    public String toString() {
        if (getVista() == ProgramacionPelicula.VISTA_PELICULA) {
            return getCine().getCine();
        } else {
            return getPelicula().getTituloOriginal();
        }
    }
    private int _idProgramacion;

    public void setIdProgramacion(int value) {
        _idProgramacion = value;
    }

    public int getIdProgramacion() {
        return _idProgramacion;
    }
    private Pelicula _pelicula;
//  public ArrayList<Pelicula> _peliculas = new ArrayList<Pelicula>();

    public void setPelicula(Pelicula pelicula) {
        _pelicula = pelicula;
    }

    public Pelicula getPelicula() {
        return _pelicula;
    }
    private Cine _cine;

    public void setCine(Cine cine) {
        _cine = cine;
    }

    public Cine getCine() {
        return _cine;
    }
    public ArrayList<Tanda> _tandas = new ArrayList<Tanda>();

    public void setTandas(ArrayList<Tanda> value) {
        _tandas = value;
    }

    public void setTandas(Object[] tandas) {
        for (Object tanda : tandas) {
            if (tanda instanceof Tanda) {
                _tandas.add((Tanda) tanda);
            }
        }
    }

    public void addTanda(Tanda value) {
        _tandas.add(value);
    }

    public ArrayList<Tanda> getTandas() {
        return _tandas;
    }
    private String _sala = "";

    public void setSala(String value) {
        _sala = value;
    }

    public String getSala() {
        return _sala;
    }
    public static final int VISTA_CINE = 0;
    public static final int VISTA_PELICULA = 1;
    private int _vista = VISTA_CINE;

    public int getVista() {
        return _vista;
    }

    public ProgramacionPelicula toPelicula() {
        ProgramacionPelicula programacionPelicula = new ProgramacionPelicula();
        programacionPelicula._idProgramacion = _idProgramacion;
        programacionPelicula._pelicula = _pelicula;
        programacionPelicula._cine = _cine;
        programacionPelicula._tandas = _tandas;
        programacionPelicula._sala = _sala;
        programacionPelicula._vista = VISTA_PELICULA;

        return programacionPelicula;
    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeInt(getIdProgramacion());
        dest.writeString(getSala());

        ArrayList<Pelicula> peliculas = new ArrayList<Pelicula>();
        peliculas.add(getPelicula());

        Object[] objectsPeliculas = peliculas.toArray();
        dest.writeArray(objectsPeliculas);

        Object[] objectsTanda = getTandas().toArray();
        dest.writeArray(objectsTanda);



    }
    // this is used to regenerate your object. All Parcelables must have a
    // CREATOR that implements these two methods
    public static final Parcelable.Creator<ProgramacionPelicula> CREATOR = new Parcelable.Creator<ProgramacionPelicula>() {

        public ProgramacionPelicula createFromParcel(Parcel in) {
            return new ProgramacionPelicula(in);
        }

        public ProgramacionPelicula[] newArray(int size) {
            return new ProgramacionPelicula[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated
    // with it's values
    private ProgramacionPelicula(Parcel in) {
        this();
        setIdProgramacion(in.readInt());
        setSala(in.readString());

        Object[] obj = in.readArray(Pelicula.class.getClassLoader());
        setPelicula((Pelicula) obj[0]);
        setTandas(in.readArray(Tanda.class.getClassLoader()));


    }
}

Thanks in advance everybody.

Upvotes: 3

Views: 12500

Answers (3)

user9547302
user9547302

Reputation: 141

The most concise, write like this:

public void writeToParcel(Parcel dest, int flags) {    
    dest.writeTypedArray(this.mMyArray, flags);
}

and read like this:

public MyParcelableObject(Parcel in) {
    this.mMyArray = in.createTypedArray(MyOtherParcelableObject.CREATOR);
}

Upvotes: 0

argenkiwi
argenkiwi

Reputation: 2427

Another way to pass an array would be using typed arrays as follows:

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeInt(mMyArray.length);
    dest.writeTypedArray(mMyArray, flags);
}

And to read it back like this:

public MyParcelableObject(Parcel in) {
    mMyArray = new MyOtherParcelableObject[in.readInt()];
    in.readTypedArray(mMyArray, MyOtherParcelableObject.CREATOR);
}

In short, write the length of the array as an int value to the parcelable, right before writing its values, so you can create an array of the same size before reading it.

Upvotes: 7

Bram Vandenbussche
Bram Vandenbussche

Reputation: 1401

In order to read/write a custom class property you need to use writeParcelable and readParcelable in stead of writing it into an array.

Change your parcel constructor to:

private ProgramacionPelicula(Parcel in) {
    this();
    setIdProgramacion(in.readInt());
    setSala(in.readString());

    _pelicula = in.readParcelable(Pelicula.class.getClassLoader());

    setTandas(in.readArray(Tanda.class.getClassLoader()));
}

And your writeToParcel method to:

@Override
public void writeToParcel(Parcel dest, int flags) {

    dest.writeInt(getIdProgramacion());
    dest.writeString(getSala());

    dest.writeParcelable(_pelicula, flags);

    Object[] objectsPeliculas = peliculas.toArray();
    dest.writeArray(objectsPeliculas);

    Object[] objectsTanda = getTandas().toArray();
    dest.writeArray(objectsTanda);
}

If you really want to use an array, you must invoke the readTypedArray/writeTypedArray methods. Like so:

@Override
public void writeToParcel(Parcel dest, int flags) {
    ArrayList<Pelicula> list = new ArrayList<Pelicula>();
    list.add(_pelicula);
    dest.writeTypedList(list);
}

private ProgrammacionPelicula(Parcel in) {
    ArrayList<Pelicula> list = new ArrayList<Pelicula>();
    in.readTypedList(list, ProgrammacionPelicula.CREATOR);
}

And you should do the same for your Tanda properties.

Hope this helps.

Upvotes: 4

Related Questions