Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


LinkedList puesto en Intent extra se refunde a ArrayList al recuperar en la actividad siguiente

Un comportamiento que estoy observando a través de pasar datos serializables como intento extra es bastante extraño, y sólo quería aclarar si hay algo que no estoy perdiendo.

Así que lo que estaba tratando de hacer es que en ActivtyA pongo una instancia LinkedList en la intent he creado para iniciar la siguiente actividad – ActivityB .

  • Cómo saber si la pantalla está encendida con ADB
  • Actualizar base de datos sqlite cuando se actualiza la base de datos del servidor
  • Uso de las actividades de los proyectos de la biblioteca
  • ¿Cuándo se debe usar Theme.AppCompat vs ThemeOverlay.AppCompat?
  • No se puede procesar Google+ SignInButton
  • Transferir InputStream a otro servicio (a través de límites de proceso) con ParcelFileDescriptor.createPipe () falla con "EBADF (número de archivo incorrecto)"
  •  LinkedList<Item> items = (some operation); Intent intent = new Intent(this, ActivityB.class); intent.putExtra(AppConstants.KEY_ITEMS, items); 

    En el onCreate de ActivityB , traté de recuperar el LinkedList extra como sigue –

     LinkedList<Item> items = (LinkedList<Item>) getIntent() .getSerializableExtra(AppConstants.KEY_ITEMS); 

    Al ejecutar esto, repetidamente obtuve una ClassCastException en ActivityB , en la línea de arriba. Básicamente, la excepción decía que estaba recibiendo un ArrayList . Una vez que cambié el código anterior para recibir un ArrayList lugar, todo funcionó bien.

    Ahora no puedo simplemente averiguar a partir de la documentación existente si este es el comportamiento esperado en Android cuando se pasa implementaciones lista serializable. O tal vez, hay algo fundamentalmente malo con lo que estoy haciendo.

    Gracias.

  • Quitar fondo dibujable mediante programación en Android
  • Android Toast Mensaje no está mostrando
  • No se puede encontrar la clase de símbolo en el código generado por Butter Knife
  • SMS Broadcastreceiver no se llama cuando GO SMS Pro instalado
  • Xlarge vs sw720dp tamaño de pantalla confusión
  • GoogleMap CameraUpdate se mueve a coordenadas incorrectas
  • One Solution collect form web for “LinkedList puesto en Intent extra se refunde a ArrayList al recuperar en la actividad siguiente”

    Puedo decirte por qué sucede esto, pero no te va a gustar 😉

    Primero un poco de información de fondo:

    Los extras en un Intent son básicamente un Bundle Android que es básicamente un HashMap de pares clave / valor. Así que cuando haces algo como

     intent.putExtra(AppConstants.KEY_ITEMS, items); 

    Android crea un nuevo Bundle para los extras y agrega una entrada de mapa al Bundle donde la clave es AppConstants.KEY_ITEMS y el valor es items (que es su objeto LinkedList).

    Esto está bien, y si tuvieras que mirar el paquete de extras después de que tu código se ejecute, encontrarás que contiene una LinkedList . Ahora viene la parte interesante…

    Cuando llama a startActivity() con la Intención que contiene extras, Android necesita convertir los extras de un mapa de pares clave / valor en una secuencia de bytes. Básicamente necesita serializar el paquete . Necesita hacerlo porque puede iniciar la actividad en otro proceso y para ello necesita serializar / deserializar los objetos en el Bundle para poder recrearlos en el nuevo proceso. También tiene que hacer esto porque Android guarda el contenido del intento en algunas tablas del sistema para que pueda regenerar el intento si necesita más tarde.

    Con el fin de serializar el Bundle en un flujo de bytes, pasa a través del mapa en el paquete y obtiene cada par clave / valor. Entonces toma cada "valor" (que es algún tipo de objeto) y trata de determinar qué tipo de objeto es para poder serializarlo de la manera más eficiente. Para ello, comprueba el tipo de objeto en una lista de tipos de objetos conocidos . La lista de "tipos de objetos conocidos" contiene cosas como Integer , Long , String , Map , Bundle y desafortunadamente List . Así que si el objeto es una List (de la cual hay muchos tipos diferentes, incluyendo LinkedList ) lo serializa y lo marca como un objeto de tipo List .

    Cuando el Bundle se deserializa, es decir: cuando haces esto:

     LinkedList<Item> items = (LinkedList<Item>) getIntent().getSerializableExtra(AppConstants.KEY_ITEMS); 

    Produce un ArrayList para todos los objetos en el Bundle de tipo List .

    Realmente no hay nada que puedas hacer para cambiar este comportamiento de Android. Al menos ahora ya sabes por qué hace esto.

    Sólo para que usted sepa: Realmente escribí un pequeño programa de prueba para verificar este comportamiento y he mirado el código fuente de Parcel.writeValue(Object v) que es el método que se llama desde Bundle cuando convierte el mapa en un byte corriente.

    Nota importante: Dado que List es una interfaz, esto significa que cualquier clase que implementa List que usted pone en un Bundle saldrá como ArrayList . También es interesante que Map esté también en la lista de "tipos de objetos conocidos", lo que significa que no importa qué tipo de objeto Map usted pone en un Bundle (por ejemplo TreeMap , SortedMap o cualquier clase que implemente la interfaz Map ), usted Siempre obtendrá un HashMap fuera de él.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.