0

I've been reading on this matter but I have not found a solution yet.

I want to use the method onSavedInstance to save an array of objects with the type Cell but all the objects inside the array will be children of Cell. My main problem is that I am not sure where to put my public static final Parcelable.Creator<MyObject> CREATOR.

Parent:

public abstract class Cell implements Parcelable{
    protected final int x;
    protected final int y;
    protected int conetion;

    ...

}

Children:

Frist:
public class Block extends Cell {
    private final Paint paint;

    ...

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(describeContents());
        out.writeInt(this.x);
        out.writeInt(this.y);
    }
}
Second:
public class Path extends Cell {

    private final Paint paint;
    private final boolean orientation;
    private Type conected;
    private int count;

    ...

    @Override
    public int describeContents() {
        return 3;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(describeContents());
        out.writeInt(this.x);
        out.writeInt(this.y);
        out.writeInt(this.conected.getColor());
        out.writeInt(this.conetion);
        out.writeInt(this.count);
    }   
}
Third:
public class Dot extends Cell {

    private final Paint paint;
    private Type conected;
    private int count;

    ...

    @Override
    public int describeContents() {
        return 2;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(describeContents());
        out.writeInt(this.x);
        out.writeInt(this.y);
        out.writeInt(this.conected.getColor());
        out.writeInt(this.conetion);
        out.writeInt(this.count);
    }
}
Fourth:
public class Path extends Cell {

    private final Paint paint;
    private final boolean orientation;
    private Type conected;
    private int count;

    ...

    @Override
    public int describeContents() {
        return 3;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(describeContents());
        out.writeInt(this.x);
        out.writeInt(this.y);
        out.writeInt(this.conected.getColor());
        out.writeInt(this.conetion);
        out.writeInt(this.count);
    }   
}

Thank you all for your time.

Carlos Morgado

CarlosMorgado
  • 315
  • 2
  • 10
  • You need to make every class in the container and the container itself Parcelable, and http://parcelabler.com can automatically do that for you. – EpicPandaForce Aug 02 '14 at 19:30
  • Yes I know I need to implement Parecelable, but my point is where do I put `public static final Parcelable.Creator CREATOR`? Do I put it in every type, or only int the parent? and how depending on the ´describeContents()´ does it recreate the array after? – CarlosMorgado Aug 02 '14 at 20:14

2 Answers2

0

I think this way: If you have a member variable that is not inherited from the parent then your child Parecelable constructor implementation is different from the parent and so the function inside your creator

public MyParcelable createFromParcel(Parcel in)

must return your child with specific constructor for it.

Other cases that you just override some functions from your parent I think you can declare it inside your parent.

mmlooloo
  • 18,937
  • 5
  • 45
  • 64
  • I can be wrong but from what I read the `public static final Parcelable.Creator CREATOR` was what called that constructor so my doubt remains... – CarlosMorgado Aug 03 '14 at 22:38
  • Yes you are right : the function public MyParcelable createFromParcel(Parcel in) must return your object so must call return new object(), so if it has a member variable that is not in its parent object can not be parent and you must return new child() other wise I think it can. – mmlooloo Aug 04 '14 at 01:10
0

Firstly, your describeContents() method should always return 0 unless you're using a FileDescriptor (which is a very unusual case).

Secondly, since your base class is abstract, you won't need a CREATOR instance for it. However, you still do need to save/restore data from it. For a simple example, take two classes, BaseParcelable and ParcelableImpl, where BaseParcelable is the abstract base class, and ParcelableImpl is a subclass with extra data:

abstract class BaseParcelable implements Parcelable {
    private int mX;
    private int mY;

    protected BaseParcelable(int x, int y) {
        mX = x;
        mY = y;
    }

    // Provide a protected constructor that subclasses can call
    // through to initialize all of the saved base class info
    protected BaseParcelable(Parcel in) {
        mX = in.readInt();
        mY = in.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        // Write out any info in this base class. No CREATOR
        // needs to be provided for this class since it is not
        // instantiable.
        parcel.writeInt(mX);
        parcel.writeInt(mY);
    }
}

And then ParcelableImpl:

public final class ParcelableImpl extends BaseParcelable {
    private int mZ;

    public ParcelableImpl(int x, int y, int z) {
        super(x, y);
        mZ = z;
    }

    // Have a constructor taking a parcel that you can use
    // to pass the parcel to the superclass
    private ParcelableImpl(Parcel in) {
        super(in);
        mZ = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        // Make sure to call through to super so that BaseParcelable
        // writes out its data first, then write additional data 
        // specific to this class implementation
        super.writeToParcel(parcel, i);
        parcel.writeInt(mZ);
    }

    // This class *does* need a creator since it's an instantiable class
    public static final Creator<ParcelableImpl> CREATOR = new Creator<ParcelableImpl>() {
        @Override
        public ParcelableImpl createFromParcel(Parcel parcel) {
            // Pass the Parcel into your Parcel constructor
            return new ParcelableImpl(parcel);
        }

        @Override
        public ParcelableImpl[] newArray(int size) {
            return new ParcelableImpl[size];
        }
    };
}
Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274