2010-10-29 20 views
54

Ho ottenuto un'implementazione di Parcelable che funziona per una singola classe che non implica alcuna ereditarietà. Ho problemi a capire il modo migliore per implementare l'interfaccia quando si tratta di ereditarietà. Diciamo che ho ottenuto questo:Parcelable and inheritance in Android

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

domanda è, quale è il metodo consigliato per implementare l'interfaccia Parcelable per la B (??? In A in entrambi Come)

+0

Hai trovato una soluzione migliore di questo da quando hai aperto questa domanda? –

+0

No, penso che la soluzione che ho proposto qui di seguito sia piuttosto semplice, per me è un fascino. –

+0

Funzionerà per uso polimorfico, come la matrice di tipo A che ha oggetti B? – vlio20

risposta

76

Qui è la mia soluzione migliore, Sarei felice di sentire da qualcuno che ci ha pensato.

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

Hai mai provato a passare la classe base su AIDL? – jsmith

+4

Abbiamo anche bisogno di implementare Parcelable in classe B (classe figlio)? –

+0

@jsmith no, non l'ho fatto, fammi sapere se ci provi. –

1

Qui è l'implementazione per la classe A in un mondo reale impostazione in quanto classe B probabilmente avrà più di un oggetto con diversi tipi diversi int

Esso utilizza la reflection per ottenere i tipi. Quindi utilizza una funzione di ordinamento per ordinare i campi in modo che la lettura e la scrittura avvengano nello stesso ordine.

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

+0

Impossibile capire la vostra soluzione, può pls postare l'impianto di classe A dall'esempio sopra .. –

+1

Hi @MohitSharma, ho aggiunto un'applicazione di esempio. Spero che aiuti –

+0

Sembra una soluzione molto utile, ma la cosa triste è che Java non crede nell'estensione di 2 classi. – Sufian

1

Questa è la mia variante. Penso che sia bello perché mostra la simmetria tra i metodi virtuali di lettura e scrittura molto chiaramente.

Nota a margine: penso che Google abbia fatto un lavoro davvero scarso nel progettare l'interfaccia 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(); 
    } 
} 
+1

Cosa succede se si desidera parcelare un elenco di A? –

+0

In 'createFromParcel()', non dovrebbe essere 'B b = new B (in);' invece di 'B b = new B(); B (in); '? Quest'ultimo (il tuo codice attuale) non verrà compilato, poiché 'b (in)' non è un metodo valido o una chiamata del costruttore. –