2010-10-29 16 views
54

Obtuve una implementación de Parcelable trabajando para una sola clase que no implica herencia. Tengo problemas para descubrir la mejor manera de implementar la interfaz cuando se trata de herencia. Digamos que tengo este:Parcelable y herencia en 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; } 
} 

La pregunta es, que es el método recomendado para implementar la interfaz parcelable para B (??? En A en ambos Cómo)

+0

¿Ha encontrado una mejor solución que esta desde que abrió esta pregunta? –

+0

No, creo que la solución que propuse a continuación es bastante sencilla, funciona como un encanto para mí. –

+0

¿Funcionará para uso polimórfico, como una matriz de tipo A que tiene objetos B? – vlio20

Respuesta

76

Aquí es mi mejor solución, Me alegraría saber de alguien que tuvo un pensamiento al respecto.

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

¿Alguna vez ha intentado pasar la clase base en AIDL? – jsmith

+4

¿Necesitamos implementar Parcelable en la clase B (clase infantil) también? –

+0

@jsmith no, no lo he hecho, avíseme si lo intenta. –

1

Aquí es la implementación de la clase A en un entorno real desde la clase B es probable que tenga más de un objeto con diferentes tipos distintos de int

Se utiliza la reflexión para obtener los tipos. Luego utiliza una función de clasificación para ordenar los campos de modo que la lectura y la escritura sucedan en el mismo orden.

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

+0

No pude entender su solución, puede publicar la implementación de la clase A del ejemplo anterior. –

+1

Hola @MohitSharma, agregué una aplicación de ejemplo. Espero que ayude –

+0

Parece una solución muy útil, pero lo triste es que Java no cree en extender 2 clases. – Sufian

1

Esta es mi variante. Creo que es bueno porque muestra la simetría entre los métodos virtuales de lectura y escritura muy claramente.

Nota al margen: creo que Google hizo un trabajo muy pobre al diseñar la interfaz 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

¿Qué sucede si quiere agregar una lista de A? –

+0

En 'createFromParcel()', ¿no debería ser 'B b = new B (in);' en lugar de 'B b = new B(); b (in); '? Este último (su código actual) no compilará, ya que 'b (in)' no es un método válido o una llamada de constructor. –