J'ai obtenu une implémentation de Parcelable fonctionnant pour une seule classe qui n'implique aucun héritage. J'ai des problèmes pour trouver la meilleure façon d'implémenter l'interface en matière d'héritage. Disons que j'ai compris ceci:
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; }
}
La question est de savoir quelle est la méthode recommandée pour implémenter l'interface Parcelable pour B (en A? Dans les deux? Comment?)
Voici ma meilleure solution, je serais heureux d'entendre quelqu'un qui y a pensé.
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();
}
}
Ceci est ma variante. Je pense que c'est sympa car cela montre très clairement la symétrie entre les méthodes de lecture et d'écriture virtuelles.
Note latérale: Je pense que Google a fait un très mauvais travail dans la conception de l'interface Parcelable.
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) {
B b = new B();
b(in);
return b;
}
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();
}
}
Voici l'implémentation de la classe A dans un environnement réel car la classe B aura probablement plus d'un objet avec des types différents autres que int
Il utilise la réflexion pour obtenir les types. Utilise ensuite une fonction de tri pour trier les champs afin que la lecture et l'écriture se déroulent dans le même ordre.