2012-10-09 20 views
5

Questo è stato chiesto alcune volte qui su SO, ma il mio caso è un po 'diverso.Parcelable ed Eredità

Ho classe A che implementa Parcelable. La classe A contiene alcuni dati dei membri che possono essere parcellizzati. Ha il proprio CREATOR e implementa writeToParcel(), describeContents() e un costruttore che accetta uno Parcel.

Esiste una classe B che si estende dalla classe A. La classe B ha dati di membro aggiuntivi, ma nessuno di questi deve essere parcellizzato. In sostanza, i dati parcelabili della classe B sono gli stessi della classe A. Se provo a inserire B in un pacchetto, a passarlo a un'altra attività e a rileggerlo, otterrei un ClassCastException. Immagino sia previsto.

Dopo un po 'di tentativi ed errori, al fine di rendere la classe B Parcelable, devo implementare almeno queste due cose:

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

Quindi la mia preoccupazione è questa. Ci sono circa mezza dozzina o più classi che si estendono da A e hanno tutti lo stesso problema di B. Sembra sciocco che ognuno di loro debba aggiungere il proprio statico CREATOR e un costruttore che accetta uno Parcel, solo per passarlo indietro a A. Tutto il resto è identico. L'unica cosa che lo rende diverso è il nome della classe. In primo luogo, batte lo scopo di avere ereditarietà.

Per esempio, se c'è un altro di classe C che si estende B, ho bisogno di fare lo stesso:

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

C'è una sorta di tecniche intelligenti in Java per automatizzare questo processo? Forse usando un generico di qualche tipo? Se non c'è altro modo, potrei anche solo rimuovere il lignaggio dell'ereditarietà e richiedere a ogni classe di implementare Parcelable.

+0

Sono un po 'in ritardo, ma ecco come ho gestito questo: http://stackoverflow.com/a/20018463/362298 –

risposta

2

Questo è un po 'complicato, ma l'unico modo in cui riesco a pensare al di fuori implica la riflessione - A condizione che tutte le sottoclassi abbiano un costruttore che prende uno super(parcel), si può rendere il nome della classe parte del pacchetto - poi nel metodo createFromParcel di 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; 
} 

si noti che questo è stato scritto in gran parte a braccio e potrebbe essere necessario qualche ritocco prima di eseguire (che so per certo che manca gestori di eccezioni controllato) - ma si spera che l'idea è clear

-1

Ho implementato la soluzione del citato da JRaymond e funziona. È un po 'complicato dal momento che comporta qualche riflessione, ma spero che aiuti qualcun altro. Ora qualsiasi classe che è parcellizzabile dovrebbe estendere questa classe GlobalParcelable che implementa parcelable.

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