Parcelable and inheritance in Android

JavaAndroidDesign PatternsInheritanceParcelable

Java Problem Overview


I got an implementation of Parcelable working for a single class that involves no inheritance. I have problems figuring out the best way to implement the interface when it come to inheritance. Let's say I got this :

public abstract class A {
    private int a;
    protected A(int a) { this.a = a; }
}

public class B extends A {
    private int b;
    public B(int a, int b) { super(a); this.b = b; }
}

Question is, which is the recommended way to implement the Parcelable interface for B (in A? in both of them? How?)

Java Solutions


Solution 1 - Java

Here is my best solution, I would be happy to hear from somebody that had a thought about it.

public abstract class A implements Parcelable {
	private int a;

	protected A(int a) {
		this.a = a;
	}

	public void writeToParcel(Parcel out, int flags) {
		out.writeInt(a);
	}

	protected A(Parcel in) {
		a = in.readInt();
	}
}

public class B extends A {
	private int b;

	public B(int a, int b) {
		super(a);
		this.b = b;
	}

	public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() {
		public B createFromParcel(Parcel in) {
			return new B(in);
		}

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

	public int describeContents() {
		return 0;
	}

	public void writeToParcel(Parcel out, int flags) {
		super.writeToParcel(out, flags);
		out.writeInt(b);
	}

	private B(Parcel in) {
		super(in);
		b = in.readInt();
	}
}

Solution 2 - Java

This is my variant. I think it's nice because it shows the symmetry between the virtual read- and write- methods very clearly.

Side note: I think Google did a really poor job at designing the Parcelable interface.

public abstract class A implements Parcelable {
    private int a;

    protected A(int a) {
        this.a = a;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(a);
    }

    public void readFromParcel(Parcel in) {
        a = in.readInt();
    }
}

public class B extends A {
    private int b;

    public B(int a, int b) {
        super(a);
        this.b = b;
    }

    public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() {
        public B createFromParcel(Parcel in) {
            return new B(in);
        }

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

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        super.writeToParcel(out, flags);
        out.writeInt(b);
    }

    public void readFromParcel(Parcel in) {
        super(in);
        b = in.readInt();
    }
}

Solution 3 - Java

Here is the implementation for class A in a real world setting since class B will likely have more than one object with different types other than int

It uses reflection to get the types. Then uses a sorting function to sort the fields so that reading and writing happen in the same order.

https://github.com/awadalaa/Android-Global-Parcelable

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVincent Mimoun-PratView Question on Stackoverflow
Solution 1 - JavaVincent Mimoun-PratView Answer on Stackoverflow
Solution 2 - JavaosxdirkView Answer on Stackoverflow
Solution 3 - JavaAlaa AwadView Answer on Stackoverflow