5

Dies wurde ein paar Mal hier auf SO gefragt, aber mein Fall ist ein bisschen anders.Parcelable und Vererbung

Ich habe Klasse A, die Parcelable implementiert. Klasse A enthält einige Elementdaten, die parzelliert werden können. Es hat seine eigene CREATOR und implementiert writeToParcel(), describeContents(), und einen Konstruktor, der eine Parcel akzeptiert.

Es gibt Klasse B, die sich von Klasse A erstreckt. Klasse B hat zusätzliche Elementdaten, aber keine davon muss parzelliert werden. Grundsätzlich sind die parzellierbaren Daten der Klasse B mit denen der Klasse A identisch. Wenn ich versuche, B in ein Bündel zu packen, es einer anderen Aktivität zu übergeben und es zurückzulesen, würde ich eine ClassCastException erhalten. Ich denke, das ist zu erwarten.

Nach einem wenig trial-and-error, um Klasse B parcel zu machen, ich habe zumindest diese beiden Dinge zu implementieren:

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

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

public B(Parcel in) throws JSONException { 
    super(in); 
} 

Also meine Sorge ist dies. Es gibt ungefähr ein halbes Dutzend oder mehr Klassen, die von A ausgehen und alle das gleiche Problem wie B haben. Es scheint albern, dass jeder von ihnen seine eigene statische CREATOR und einen Konstruktor hinzufügen muss, der eine Parcel akzeptiert, nur um sie zurück zu geben zu A. Alles andere ist identisch. Das einzige, was es anders macht, ist der Name der Klasse. Es übertrifft den Zweck, Erbschaft an erster Stelle zu haben.

Zum Beispiel, wenn es eine andere Klasse C ist die B erstreckt, muss ich das gleiche tun:

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

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

public C(Parcel in) throws JSONException { 
    super(in); 
} 

Gibt es irgendeine Art von cleveren Techniken in Java, diesen Prozess zu automatisieren? Vielleicht mit generischen irgendeiner Art? Wenn es keinen anderen Weg gibt, kann ich genauso gut die Vererbungslinie entfernen und von jeder Klasse verlangen, dass sie Parcelable selbst implementiert.

+0

Ich bin ein wenig spät, aber hier ist, wie ich diese behandelt: http://stackoverflow.com/a/20018463/362298 –

Antwort

2

Dies ist ein wenig kompliziert, aber der einzige Weg, ich offhand denken kann, beinhaltet Reflexion - vorausgesetzt die Unterklassen einen Konstruktor haben, die eine Parcel nimmt, die dann super(parcel) nennt, könnte man den Klassennamen einen Teil des Pakets machen - dann in Ihrem createFromParcel Methode A:

public A createFromParcel(Parcel source) { 
    Class clazz = Class.forName(source.readString()); 
    Class[1] paramTypes = { Parcel.class }; 
    Constructor ctor = clazz.getConstructor(paramTypes); 
    A myA = (A) ctor.newInstance(source); 
    return myA; 
} 

Beachten sie, dass dies weitgehend aus dem Stehgreif geschrieben und kann einige Optimierungen müssen, bevor es läuft (ich weiß sicher, geprüft Exception-Handler fehlt) - aber hoffentlich die Idee ist, clear

-1

Ich habe die Lösung des implementiert kritisiert von JRaymond und es funktioniert. Es ist ein wenig kompliziert, da es etwas Reflexion beinhaltet, aber ich hoffe, es hilft jemand anderem. Jetzt sollte jede Klasse, die parcelable ist, diese GlobalParcelable-Klasse erweitern, die parcelable implementiert.

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