2012-09-02 15 views
49

tengo una clase que implementa la interfaz Parcelable:escribir una clase sub de parcelable a otro paquete

class A implements Parcelable { 

} 

Tengo otra clase B que contiene un objeto A como una variable de instancia. En el interior de la clase writeToPacelB, quiero escribir objeto B a la Parcel:

class B implements Parcelable{ 

    public void writeToParcel(Parcel dest, int flags) { 
     dest.write ??? 
    } 
} 

¿Cómo puedo escribir y leer?

+0

¿Dónde está el 'A object' interior B? – iTurki

Respuesta

143
class B implements Parcelable{ 
//lets assume you have A as a data member 

A obj; 
public void writeToParcel(Parcel dest, int flags) { 

     dest.writeParcelable(obj , flags); 

    } 
} 

si quieres leerlo utilizar este

obj = in.readParcelable(A.class.getClassLoader()); 
+0

Ayudé este código ... !!!!!!!!!!!!!! –

+5

No hay necesidad de fundición :) – pablisco

+4

Puede ser aún más preciso: 'obj = (A) en. readPecelable (A.class.getClassLoader());' – caw

2

La línea:

obj = (A)in.readParcelable(A.class.getClassLoader()); 

debe cambiar a:

obj = (A)in.readParcelable(B.class.getClassLoader()); 

me encontré con el mismo problema y lo hice varias búsquedas en Google, muchas páginas web o tutoriales sugieren usamos A.class.getClassLoader() porque estamos lanzando a A, pero en realidad es INCORRECTO porque obtendrá un valor nulo, debemos usar B.class.getClassLoader() porque codes are INSIDE class B. Simplemente no sabía por qué, pero puede obtener el objeto A correcto de esta manera.

Bienvenido a comentar y verificar !!

10

Una mejor manera de manejar esto que evita la reflexión sería llamar simplemente el creador estática en el tipo de destino así:

this.amazingObject = AmazingObject.CREATOR.createFromParcel(in); 

y escribirla en el Parcelable usando this.amazingObject.writeToParcel(Parcel, int)

Internamente, cuando llamando readParcelable(ClassLoader) esto sucede:

public final <T extends Parcelable> T readParcelable(ClassLoader loader) { 
    Parcelable.Creator<T> creator = readParcelableCreator(loader); 
    if (creator == null) { 
     return null; 
    } 
    if (creator instanceof Parcelable.ClassLoaderCreator<?>) { 
     return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader); 
    } 
    return creator.createFromParcel(this); 
} 

Como se puede ver la última llamada de ese método es J ust llamando a la derecha Creator pero dentro de readParcelableCreator hay una gran cantidad de reflexión que podemos evitar simplemente llamándola directamente. llamadas

esta utilidad pueden ser útiles:

import android.os.Parcel; 
import android.os.Parcelable; 

public class Parcels { 

    public static void writeBoolean(Parcel dest, Boolean value) { 
     dest.writeByte((byte) (value != null && value ? 1 : 0)); 
    } 

    public static Boolean readBoolean(Parcel in){ 
     return in.readByte() != 0; 
    } 

    public static void writeParcelable(Parcel dest, int flags, Parcelable parcelable) { 
     writeBoolean(dest, parcelable == null); 
     if (parcelable != null) { 
      parcelable.writeToParcel(dest, flags); 
     } 
    } 

    public static <T extends Parcelable> T readParcelable(Parcel in, Parcelable.Creator<T> creator) { 
     boolean isNull = readBoolean(in); 
     return isNull ? null : creator.createFromParcel(in); 
    } 

} 
+1

Lanza una excepción cuando el objeto es nulo, mientras que '' readParcelable'' maneja esta situación correctamente – dragoon

+0

@dragoon ¿Cuál es la excepción que obtienes? – pablisco

+0

¡Termino utilizando mi propio Parcel Util, pero gracias por la inspiración! – Juancho

Cuestiones relacionadas