2011-01-31 18 views
24

Soy totalmente nuevo para publicar preguntas aquí, sin embargo, he estado leyendo mucho aquí durante años. Normalmente siempre puedo encontrar mis respuestas buscando en la web, pero esta vez estoy perdido ...Android: Parcelable.writeToParcel y Parcelable.Creator.createFromParcel nunca se llaman

Después de haber pasado un día más tratando de descubrir por qué esto no funciona, decidí preguntar por ayuda, esperando que ustedes puedan darme algunos consejos, o mejor, una solución.

El problema: En un juego de Android he llegado al punto en el que tengo que hacer que la aplicación recuerde su estado cuando un usuario, p. Ej. presiona el botón de la pantalla HOME. Después de algunas búsquedas, me di cuenta de que para hacer que mis clases se inicializaran de nuevo en sus estados apropiados después de volver a abrir la aplicación, tenía que admitir la interfaz Parcelable para pasarlas con el Bundle.

En mis funciones onStop y onStart, guardo y restablezco el estado del juego ay desde un Bundle, pero cuando llamo a las funciones putParcelable y getParcelable en el Bundle las funciones writeToParcel y createFromParcel del objeto nunca son llamadas.

Temiendo que esto pueda deberse a la relativa complejidad del juego, pensé que sería mejor que creara una aplicación muy simple para intentar que funcione.

Sobre la base de muchos ejemplos parcelable que he visto en línea, esto se convirtió en mi clase:

public class ParcelableTest implements Parcelable { 
    int id; 

    public ParcelableTest(int newID) 
    { 
    id = newID; 
    } 

    private ParcelableTest(Parcel in) { 
     readFromParcel(in); 
    } 

    public void writeToParcel(Parcel out, int arg1) { 
     writeToParcel(out); 
    } 

    public void writeToParcel(Parcel out) { 
    Log.v("ParcelableTest","Writing to parcel"); 
     out.writeInt(id); 
    } 

    public void readFromParcel(Parcel in) { 
     id = in.readInt(); 
    } 

    public int describeContents() { 
     return 0; 
    } 

    public static final Parcelable.Creator<ParcelableTest> CREATOR = new 
    Parcelable.Creator<ParcelableTest>() { 
     public ParcelableTest createFromParcel(Parcel in) { 
      Log.v("ParcelableTest","Creating from parcel"); 
       return new ParcelableTest(in); 
     } 

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

Y desde mi actividad principal que yo llamaría las siguientes funciones para salvar/restaurar los datos:

public Bundle saveToBundle(Bundle savedState) 
    { 
     savedState.putParcelable("Test1",mTest1); 
     savedState.putParcelable("Test2",mTest2); 
     return savedState; 
    } 
    public void restoreFromBundle(Bundle savedState) 
    { 
     mTest1 = savedState.getParcelable("Test1"); 
     mTest2 = savedState.getParcelable("Test2"); 

    } 

Pero por alguna razón, ninguna de las funciones (con las funciones putParcelable y getParcelable) dará como resultado las llamadas Parcelable apropiadas en mi clase de prueba.

Lo más extraño es que de alguna manera lee los valores correctos (lo he intentado con más variables en la clase), pero mi depuración y mi registro muestran que esa aplicación nunca llega a writeToParcel y createFromParcel.

¿Qué me falta aquí?

Cualquier ayuda/idea sería apreciada.

+0

Si la respuesta resolvió tu pregunta, ¿marcarías eso? ¿O encontró una mejor solución para su problema? ¿Podrías publicar eso aquí? – superjos

Respuesta

10

Aparentemente, la clase Android Bundle no se adhiere al protocolo parcelable que en su lugar se sigue durante la clasificación de IPC.

En su lugar, parece que la implementación de Bundle simplemente escribe y lee el objeto Parcelable en su propio mapa interno por medio de la reflexión. De una prueba que hicimos, parece que el Bundle escribe/lee cada campo definido en su clase derivada Parcelable, simplemente porque usted ha declarado esos campos.

+2

Esto parece ser cierto, excepto en los momentos en que se destruye la actividad, cuando se invocan los métodos de parcelamiento. – newfivefour

+0

Lo mismo aquí. Ni siquiera marcar una variable como transitorio ayudará. Todavía será serializado. Este es el comportamiento inesperado al introducir errores desagradables. ¿Alguno de ustedes abrió un tic sobre esto? – MaiOM

+0

No, no lo hicimos. Mirando hacia atrás, probablemente pensamos que era algo * demasiado cercano * a los detalles de implementación en comparación con el propósito que el paquete se supone que debe servir. Básicamente, estoy de acuerdo con lo que escribió @Luis. – superjos

4

Técnicamente, la documentación no dice que writeToParcel o createFromParcel se llaman desde onSaveInstance. De hecho, si marca el savedState en su código, encontrará que es exactamente la misma instancia de objeto en los casos de guardar y restaurar; tiene sentido evitar serialize-deserialize si puedes.
OTOH, la documentación tampoco dice que la serialización no está completa. La conclusión debería ser que no debe depender de ninguno de los casos, solo suponga que obtiene el paquete correcto.

Además, es posible que desee comprobar http://developer.android.com/guide/topics/resources/runtime-changes.html

0

confirmo lo que dijeron superjos. En el evento saveToBundle, el paquete de Android simplemente almacena los miembros de la clase por reflexión y no llama a las funciones Parcelable. ¡He perdido un día en este problema! triste ....

Esto es realmente malo .... Esto significa que potencialmente almacena una gran cantidad de datos para nada de esta manera.

Cuestiones relacionadas