Parcelable and Inheritance in Android

Parcelable and inheritance in Android

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();
}
}

Parcelable inheritance in aidl

EDIT: I had the names sharp and rect confused, so I've swapped them to avoid confusion

You just implement it like this:

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

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

You aren't overriding the field in Sharp, because static fields cannot be overriden. You are hiding the field. That means if someone writes:

Parcelable.Creator<Rect> creator = Rect.CREATOR;

they get a different object than if someone writes:

Parcelable.Creator<Sharp> creator = Sharp.CREATOR;

Note: I took the liberty of capitalizing your class names Rect and Sharp. You should also do it. It will make your life easier and your code will look more like Java ;-)

EDIT: Added some additional clarification after OP's comments

I think I see your problem. You want to define an interface that passes a Sharp object, but you really want to pass a derived Rect object and this object is recreated as a Sharp object on the receiving end. It looks like AIDL doesn't support this kind of inheritance. However, what you could do is something like this (poor-man's factory):

In Rect:

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(getClass().getName());
// Write other instance variables
}

In Sharp:

public static final Parcelable.Creator<Sharp> CREATOR
= new Parcelable.Creator<Sharp>() {
public Sharp createFromParcel(Parcel in) {
String derivedClassName = in.readString();
if (derivedClassName.equals(Rect.class.getName()) {
// Create an instance of Rect and return that
return new Rect(in);
} else if (derivedClassName.equals(...) {
// Possible other derived classes
}
}

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

Note that the constructor

public Rect(Parcel in)

will get called with the class name String already removed from the incoming Parcel.

Android Parcelable and inheritance

In your AddDrill class, you'll need to implement writeToParcel() method and also the constructor from a Parcel. You'll probably need to use @Override for both of such methods as well but you need to experiment to find out the final solution



Related Topics



Leave a reply



Submit