2013-04-10 10 views
8

Ho uno stato che voglio salvare attraverso il ciclo di vita di un frammento. Funziona bene quando lo schermo ruota, ad esempio, ma quando il processo è stato ucciso e ripristinato dal disco (penso che sia così che funziona), ottengo un ClassCastException. Ecco po 'di codice:ClassCastException durante il recupero dei dati dal bundle su Android

inizializzazione:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (savedInstanceState == null) { 
     playlistsMap = new LinkedHashMap<Section, List<Playlist>>(); 
    } else { 
     playlistsMap = (LinkedHashMap<Section, List<Playlist>>) savedInstanceState.getSerializable(PLAYLISTS_MAP_KEY); 
    } 
    setHasOptionsMenu(true); 
} 

Protezione dei dati:

@Override 
public void onSaveInstanceState(Bundle outState) { 
    if (isEverySectionsLoaded()) { 
     outState.putSerializable(PLAYLISTS_MAP_KEY, playlistsMap); 
    } else { 
     outState.putSerializable(PLAYLISTS_MAP_KEY, new LinkedHashMap<Section, List<Playlist>>()); 
    } 
    // ... 
} 

L'eccezione ricevo dal cast in onCreate:

04-10 01:06:43.430 E/AndroidRuntime(28549): FATAL EXCEPTION: main 
04-10 01:06:43.430 E/AndroidRuntime(28549): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.android/com.mydomain.android.ui.MainActivity}: 
java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap 

So che è meglio usare parcelables su Android, ma ancora non capisco come potrebbe mai accadere.

Qualche idea?

+0

Nel mio caso, Hashtable è stato salvato in acrossInstanceState. Quando ruoto lo schermo, otteniamo l'hashtable, ma nel caso in cui l'app si arresti in modo anomalo, come hai detto, otteniamo una Hashmap e quindi un'eccezione cast di classe. Sei riuscito a trovare qualche buona soluzione o soluzione per questo? – Nil

risposta

11

lettura interessante riguardante una domanda simile può essere trovato here

Qualsiasi oggetto che implementa sia java.util.List e java.io.Serializable diventerà ArrayList dopo intent.putExtra (EXTRA_TAG, suchObject) /startActivity(intent)/intent.getSerializableExtra(EXTRA_TAG).

Oserei dire che lo stesso vale per tutto ciò che implementa serializzabile e mappa. Quella HashMap è l'impostazione predefinita a cui tornerai.

Una soluzione intorno a questo quello che sembra un bug sarebbe qualcosa di simile a:

private LinkedHashMap<Section, List<Playlist>> playlistsMap; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (savedInstanceState == null) { 
     playlistsMap = new LinkedHashMap<Section, List<Playlist>>(); 
    } else { 
     //assuming the bug returns a hashmap 
     Map<Section, List<Playlist>> items = (Map<Section, List<Playlist>>) savedInstanceState.getSerializable(PLAYLISTS_MAP_KEY); 

     //this way you can ensure you are working with a linkedHashMap. 
     //for the rest off the application 
     playlistsMap.putAll(items); 
    } 
    setHasOptionsMenu(true); 
} 

Il codice di cui sopra non è testato, ma dovrebbe funzionare. Questo codice funzionerà ancora quando il bug viene corretto a causa dell'uso delle interfacce. Così puoi stare tranquillo quando il tuo cliente ottiene un aggiornamento Android che il tuo codice dovrebbe continuare a fare lo stesso invece di andare in crash e lamentarsi del fatto che non puoi trasmettere una HashMap a una LinkedHashMap.

+0

Sì. So che LinkedHashMap e HashMap non sono intercambiabili, semplicemente non so da dove provenga HashMap. I metodi putSerializable/getSerializable non sono suposed per avere alcuna conoscenza di ciò che sto mettendo a parte dal fatto che implementano Serializable ... – kombucha

+0

Mmhm, potrebbe essere un bug nelle stesse librerie Android allora. Ho letto molte persone che hanno problemi simili a te. Devo ancora trovare una risposta al "perché" però. Continuerò a cercare e ti faccio sapere se trovo di più.Per una soluzione temporanea, puoi lanciarla su una mappa. Questo dovrebbe funzionare, se si lamenta di lanciare su una HashMap –

+0

edita la mia risposta con un link, potrebbe essere una lettura interessante. –

-2

Il problema è che il riferimento restituito semplicemente non è un riferimento a un'istanza di LinkedHashMap. Se la funzione Restituisce LinkedHashMap restituisce semplicemente un valore LinkedHashMap, non può essere trasmesso su HashMap.

+0

So cosa significa la classificazione di qualità, semplicemente non so da dove viene. Sto mettendo una LinkedHashMap nel pacchetto come Serializable, mi aspetto bundle.getSerializable per restituirmi lo stesso oggetto. – kombucha

+0

controlla dove hai ottenuto LinkedHashMap –

+0

e trasferito in HashMap. –