¿Recuperar un objeto parcelable a través de un paquete siempre crea una nueva copia?

Estoy pasando un objeto parcelable a un fragmento agregándolo a un paquete mientras creaba el fragmento. En la instancia ONC, la modificación de este objeto parcelado refleja la modificación en el objeto original y en otro caso no lo es. Estoy un poco desconcertado por este comportamiento. Hasta ahora he asumido la recuperación de objetos parcelados a través de un paquete siempre crear nuevo objeto [no seguro si es copia superficial o copia profunda].

Alguien por favor aclare el comportamiento parcelable.

Yo estaba luchando con un problema similar. A primera vista parece que siempre obtenemos una nueva copia profunda de los objetos divididos. Además, hay incluso algunas respuestas de StackOverflow que sugieren utilizar la interfaz Parcelable para clonar objetos. Todo esto sólo aumenta la confusión sobre el tema.

Aquí es lo que he encontrado después de un montón de búsqueda y google:

  • Echa un vistazo a la documentación oficial de Parcel . Aquí está la cita importante:

Una característica inusual de Parcel es la capacidad de leer y escribir objetos activos. Para estos objetos no se escribe el contenido real del objeto, sino un token especial que hace referencia al objeto que se escribe. Al leer el objeto desde el paquete, no se obtiene una nueva instancia del objeto, sino un identificador que funciona en el mismo objeto que se escribió originalmente.

Ok, como puedes ver, hay algunos objetos especiales que no se están copiando durante unparceling. Pero esto todavía es un poco confuso. ¿Significa que tenemos otra fuerte referencia al objeto original que impide su recolección de basura? ¿Y cuáles son los casos de uso para tales objetos?

  • Para responder a las preguntas mencionadas, decidí buscar a través del código fuente de Android. Los métodos que estaba buscando son readStrongBinder y writeStrongBinder que de acuerdo con los documentos no causan una nueva creación de objetos cuando se envían / ​​reciben los paquetes. Y creo que encontré la respuesta deseada en la clase ResultReceiver.java . Aquí está la interesante línea:

     mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder()); 

    Para entender qué es lo que realmente está haciendo esta línea debemos ir a la documentación oficial de AIDL . Estas son las partes más importantes:

Los pasos que debe tomar una clase llamante para llamar a una interfaz remota definida con AIDL:

5. En su implementación de onServiceConnected (), recibirá una instancia de IBinder (denominada servicio). Llame al servicio YourInterfaceName.Stub.asInterface ((IBinder)) para emitir el parámetro devuelto al tipo YourInterface.

Algunos comentarios sobre cómo llamar a un servicio IPC:

Los objetos son referencia contada a través de procesos.

Así que vamos a poner todas las cosas juntos:

  1. Los objetos parcelados se pueden extraer sin implicar el proceso profundo de la copia.
  2. Si los objetos parcelados se leen mediante el método readStrongBinder no se crean nuevas instancias. Sólo objtain una nueva referencia al objeto original y esta referencia puede prevenir su dealllocation.
  3. Para saber si nuestro objeto será copiado profundamente después de que el paquete se ha recibido que debemos tomar una mirada más cercana a la aplicación concreta de la interfaz de Parcelable .
  4. La documentación de Android puede ser muy confusa y puede tomar mucho tiempo entenderla correctamente.

Espero que esta información le ayudará.

Si quieres leer acerca de un ejemplo del mundo real, cuando la confusión respecto a los objetos Parcelable puede causar serios problemas echa un vistazo a mi blog .

  • Parcelable y herencia en Android
  • ¿Qué es una comunicación más rápida usando un mensajero o una intención?
  • Android Class Parcelable con ArrayList
  • Android BadParcelableException sólo con apk firmado
  • Clase abstracta como parcelable
  • ¿Cómo hacer una interfaz parcelable?
  • Transmisión de JSONObject a otra actividad
  • Android: ¿Cómo pasar el objeto Parcelable a la intención y el uso getParcelable método de paquete?
  • Leer y escribir arreglos de objetos parcelables
  • NullPointerException intentando leer Parcel String
  • No se puede guardar ArrayList de Uri en un archivo: NotSerializableException
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.