2012-07-01 12 views
7

ClassCastException si verifica in modo casuale per ripristinare Vector in onRestoreInstanceState(). Generalmente il ripristino del vettore è terminato correttamente, ma a volte si verifica un'eccezione.ClassCastException si verifica in onRestoreInstanceState

Penso che succeda quando l'attività è passata allo sfondo e distrutta ma non ne sono sicuro.

Qualche idea? Grazie.

Stack<LocationInfo> mLocationInfoVector; 

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    outState.putSerializable("locationInfos", mLocationInfoVector); 

    super.onSaveInstanceState(outState); 
} 

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) { 
    if (savedInstanceState.getSerializable("locationInfos") != null) { 
     @SuppressWarnings("unchecked") 
     mLocationInfoVector= (Stack<LocationInfo>) savedInstanceState.getSerializable("locationInfos"); 
    } 

    super.onRestoreInstanceState(savedInstanceState); 
} 

aggiunto:

Ho dimenticato di allegare log eccezione. Cioè

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Stack 
+1

Suggerisco di riscrivere il metodo 'onRestoreInstanceState' come segue:' Oggetto salvato = savedInstanceState.getSerializable ("locationInfos"); if (saved instanceof Stack) {mLocationInfoVector = (Stack ) salvato; } else if (saved! = null) {Log.e ("RestoreBug", "Classe oggetto ripristinato:" + saved.getClass(). getName()); } 'Quindi puoi almeno vedere cosa stai tornando. (Ci scusiamo per aver postato il codice in un commento, non voglio postare questo come risposta). –

+0

Ho pensato in questo modo, ma voglio davvero sapere quale meccanismo rende questo caso. Ho aggiunto il registro delle eccezioni e non so perché il tipo di oggetto sia cambiato in ArrayList. – chris

+0

Per caso la superclasse della tua attività sovrascrive 'onSaveInstanceState'? Mi chiedo se stai usando la chiave "locationInfos" in qualsiasi altra parte del tuo codice. (P.S. in ogni caso, dovresti riorganizzare il tuo codice 'onRestoreInstanceState' in modo che chiami solo' getSerializable() 'una volta.) –

risposta

5

Io uso codice successivo per ripristinare Vector:

objects = new Vector<Object>((Collection<Object>) state.getSerializable(EXTRA_OBJECTS)); 

Previene java.lang.ClassCastException e salva ordine elementi.

Per ripristinare stack, è possibile utilizzare il codice seguente:

stack = new Stack<Object>(); 
stack.addAll((Collection<Object>) state.getSerializable(EXTRA_STACK)); 

Funziona a causa di vettore, Catasta, ArrayList stanno estendendo Collection, e si può lanciare l'oggetto serializzato per raccolta e passare al camino o Vector addAll() metodo.

+0

ragazzo, questo è incasinato. Grazie. –

4

genere questo accade quando l'attività è stata distrutta a causa della pressione di memoria. Il bundle passato a onRestoreInstanceState sembra conservare un'istanza della classe base (ArrayList in questo caso).

Si può essere in grado di riprodurre il problema modificando le opzioni per sviluppatori:

  1. vai a Impostazioni | Opzioni sviluppatore
  2. Controllare la casella "Non tenere attività"

Ora la vostra attività saranno distrutti immediatamente dopo si lascia. Avviare l'attività in questione, premere il pulsante Home e quindi tornare alla tua app dovrebbe attivare lo ClassCastException.

Nel frattempo, il suggerimento di Ted Hopp da usare

if (saved instanceof Stack) { 
    .... 
} 

dovrebbe evitare crash l'applicazione.

+0

Ancora non conosco il meccanismo che il valore salvato esiste nel pacchetto, ma il tipo è stato modificato. – chris

Problemi correlati