posso dirvi perché questo sta accadendo, ma non stanno andando come si ;-)
Prima un po 'di informazioni di base:
Extra in un Intent
sono fondamentalmente un Android Bundle
che è fondamentalmente un HashMap
di coppie chiave/valore. Così, quando si fa qualcosa di simile
intent.putExtra(AppConstants.KEY_ITEMS, items);
Android crea un nuovo Bundle
per gli extra e aggiunge una voce di mappa per la Bundle
in cui la chiave è AppConstants.KEY_ITEMS
e il valore è articoli (che è l'oggetto LinkedList).
Questo è tutto a posto, e se si dovesse esaminare il pacchetto extra dopo l'esecuzione del codice, si scoprirà che contiene uno LinkedList
. Ora arriva la parte interessante ...
Quando si chiama startActivity()
con l'intento contenente extra, Android deve convertire gli extra da una mappa di coppie chiave/valore in un flusso di byte. Fondamentalmente è necessario serializzare il pacchetto. Deve farlo perché può avviare l'attività in un altro processo e per fare ciò ha bisogno di serializzare/deserializzare gli oggetti nel Bundle in modo che possa ricrearli nel nuovo processo. Deve anche farlo perché Android salva i contenuti dell'Intent in alcune tabelle di sistema in modo che possa rigenerare l'Intent se è necessario in seguito.
Per serializzare Bundle
in un flusso di byte, passa attraverso la mappa nel gruppo e ottiene ogni coppia chiave/valore. Quindi prende ogni "valore" (che è una specie di oggetto) e cerca di determinare che tipo di oggetto è in modo che possa serializzarlo nel modo più efficiente. Per fare ciò, controlla il tipo di oggetto con un elenco di tipi di oggetto noto .L'elenco di "tipi di oggetto conosciuti" contiene cose come Integer
, Long
, String
, Map
, Bundle
e purtroppo anche List
. Quindi se l'oggetto è un List
(di cui esistono molti tipi diversi, incluso LinkedList
) lo serializza e lo contrassegna come un oggetto di tipo List
.
Quando il Bundle
viene deserializzato, vale a dire: quando si esegue questa operazione:
LinkedList<Item> items = (LinkedList<Item>)
getIntent().getSerializableExtra(AppConstants.KEY_ITEMS);
produce un ArrayList
per tutti gli oggetti nel Bundle
di tipo List
.
Non c'è davvero nulla che tu possa fare per modificare questo comportamento di Android. Almeno ora sai perché lo fa.
solo in modo che si sa: in realtà ho scritto un piccolo programma di test per verificare questo comportamento e ho guardato il codice sorgente per Parcel.writeValue(Object v)
che è il metodo che viene chiamato da Bundle
quando converte la mappa in un flusso di byte.
Nota importante: Dal List
è un'interfaccia questo significa che ogni classe che implementa List
che si mette in un Bundle
uscirà come un ArrayList
. E 'anche interessante il fatto che Map
è anche nella lista dei "tipi di oggetto conosciuto", che significa che non importa che tipo di Map
oggetto si inserisce in un Bundle
(ad esempio TreeMap
, SortedMap
, o qualsiasi classe che implementa l'interfaccia Map
), ne otterrai sempre uno HashMap
.
utilizzare Parcelable. –
ma c'è qualche ragione particolare per cui per 'LinkedList' questo comportamento si verifica, mentre, se dovessi aggiungere un'istanza di' ArrayList' come dati extra sull'intento 'tutto andrebbe bene. E non avrò bisogno di usare 'Parcelable'? – anirvan
+1 per la domanda interessante. Ho passato un po 'di tempo a pensare a questo ed ero così incuriosito che sono andato a capirlo da solo. Ora tu ed io siamo entrambi più intelligenti (vedi la mia risposta). –