DERIIIFranz DERIIIFranz - 5 months ago 55
Java Question

Abstract class as parcelable

Basicly I have the following structure in my app:

uml of my app

It would be straightforward to implement such a structure without the abstract class

ProjectItem
, but in this case I don't know how to implement this.

The abstract class
ProjectItem
needs a
CREATOR
as it should be parcelable. (like
in.readTypedList(mProjectItems, ProjectItem.CREATOR);
within the constructor Project(Parcel in))

But in fact, the
CREATOR
can only be implemented in its derived classes for logical reasons.

So, how to implement this structure in order to keep the class
Project
parcelable??

Edit

This is what one of the constructors of
Project
looks like:

private Project(Parcel in) {
in.readTypedList(mProjectItems, ProjectItem.CREATOR);
}


But as I already said,
ProjectItem
shouldn't have to implement a
CREATOR

Answer

The selected answer (from evertvandenbruel's post) has a bug in it. The correct code must account for parceling when just one of the subclasses is being parceled, not just a list of the superclass objects.

All the other code should be the same, the key is that you MUST read in the type variable in ALL creators (see code below). Otherwise there will be issues with the ordering when trying to unparcel a subclass object

Ex:

package com.example.parcelable_example.model;

import android.os.Parcel;
import android.os.Parcelable;

public class Cat extends Animal{

    public Cat(String name){
        super(name, "Cat");
    }

    public int describeContents() {
        return this.hashCode();
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(getType());
        super.writeToParcel(dest, flags);
    }

    public Cat(Parcel source) {
        super(source);      
    }

    public static final Parcelable.Creator<Cat> CREATOR = new Parcelable.Creator<Cat>() {
        public Cat createFromParcel(Parcel in) {
            /** DO NOT FORGET THIS!!! **/
            type = in.readString();
            return new Cat(in);
        }

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

}
Comments