os por qué ocurre esto puedo decir, pero que no van a gustar ;-)
Primero un poco de información de fondo:
Extras en un Intent
son, básicamente, un Android Bundle
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
por los extras y añade una entrada de mapa a la Bundle
donde la clave es AppConstants.KEY_ITEMS
y el valor es artículos (que es su objeto LinkedList).
Todo está bien y bien, y si tuviera que mirar el paquete de extras después de que se ejecute su código, encontrará que contiene un LinkedList
. Ahora viene la parte interesante ...
Cuando llamas al startActivity()
con el contenido que contiene extras, Android necesita convertir los extras de un mapa de pares clave/valor en un flujo de bytes. Básicamente se necesita serializar el paquete. Tiene que hacer eso porque puede iniciar la actividad en otro proceso y para hacerlo necesita serializar/deserializar los objetos en el paquete para que pueda recrearlos en el nuevo proceso. También necesita hacer esto porque Android guarda los contenidos del Intent en algunas tablas del sistema para que pueda regenerar el Intento si lo necesita más tarde.
Para serializar el Bundle
en una secuencia de bytes, pasa por el mapa en el paquete y obtiene cada par de clave/valor. Luego toma cada "valor" (que es algún tipo de objeto) e intenta determinar qué tipo de objeto es para poder serializarlo de la manera más eficiente. Para hacer esto, comprueba el tipo de objeto con una lista de tipos de objetos conocidos.La lista de "tipos de objetos conocidos" contiene cosas como Integer
, Long
, String
, Map
, Bundle
y lamentablemente también List
. Por lo tanto, si el objeto es un List
(del que hay muchos tipos diferentes, incluido LinkedList
) lo serializa y lo marca como un objeto de tipo List
.
Cuando se deserializa el Bundle
, es decir: cuando se hace esto:
LinkedList<Item> items = (LinkedList<Item>)
getIntent().getSerializableExtra(AppConstants.KEY_ITEMS);
Produce un ArrayList
para todos los objetos del tipo de Bundle
List
.
No hay nada que puedas hacer para cambiar este comportamiento de Android. Al menos ahora sabes por qué hace esto.
Sólo para que sepa: De hecho, me escribió un pequeño programa de prueba para verificar este comportamiento y me han mirado el código fuente de Parcel.writeValue(Object v)
que es el método que es llamada desde Bundle
cuando convierte el mapa en un flujo de bytes.
Nota importante: Desde List
es una interfaz esto significa que cualquier clase que implementa List
que usted pone en un Bundle
saldrá como un ArrayList
. También es interesante que Map
también está en la lista de "tipos de objetos conocidos", que significa que no importa qué tipo de Map
objeto que puso en un Bundle
(por ejemplo TreeMap
, SortedMap
, o cualquier clase que implementa la interfaz Map
), siempre obtendrás un HashMap
.
use Parcelable en su lugar. –
, pero ¿hay algún motivo en particular para que 'LinkedList' ocurra este comportamiento, mientras que, si tuviera que agregar una instancia 'ArrayList' como datos adicionales en el' intento', todo estaría bien. Y, ¿no necesitaré usar 'Parcelable'? – anirvan
+1 para la pregunta interesante. Pasé un tiempo pensando en esto y estaba tan intrigado que fui a resolverlo por mí mismo. Ahora tú y yo somos más inteligentes (ver mi respuesta). –