2013-03-25 13 views
21

Ho frammenti che tengo nel backstack di FragmentManager. Ogni stato frammento è salvata per cambiamenti di orientamento con le variabili membro, in questo modo, per esempio:Utilizzo di onSaveInstanceState con frammenti nel backstack?

@Override 
public void onSaveInstanceState(Bundle outState) 
{ 
    super.onSaveInstanceState(outState); 
    outState.putLong("userId", mUserId); 
    outState.putString("username", mUsername); 
} 

mio problema è che se c'è un cambiamento di orientamento, dal momento che ogni frammento nel backstack viene chiamato via onSaveInstanceState, ottengo un null eccezione puntatore perché le variabili membro non esistono più.

Qualche idea su come risolvere questo?

+0

puoi fornire il tuo messaggio di errore logcat? –

+0

onSaveInstanceState viene chiamato prima che venga applicata la modifica effettiva, quindi le variabili dovrebbero esistere quando le chiamate, a meno che non siano nulle a causa di altri errori nel codice. Pubblica un altro codice insieme al modulo di output degli errori Logcat. – Shade

+0

Posso assicurarti che le mie variabili vanno bene. Penso che il problema è che i miei frammenti nel backstack non stanno ricevendo onSaveInstanceState quando vengono abbattuti; onSaveInstanceState viene chiamato solo quando l'attività viene distrutta, ma le mie variabili non esistono più. Quindi la mia attuale soluzione è: "if (mUserId! = Null && mUsername! = Null) ...". Non è carino, ma risolve il problema. Trovo strano avere un metodo onSaveInstanceState per i frammenti se non viene chiamato quando il frammento viene rimosso. –

risposta

34

È possibile che le variabili membro non esistano più perché FragmentManager nel tuo Activity sta morendo con tutti i tuoi frammenti.

È necessario eseguire l'override del metodo onSaveInstanceState della classe Activity così, perché è necessario salvare lo stato Activity prima di salvare lo stato Fragments.

Come il documentation dice:

Ci sono molte situazioni in cui un frammento può essere in gran parte abbattuta (ad esempio, quando sono immessi sulla pila avanti senza che mostra UI), ma il suo stato non saranno salvati finché la sua attività proprietaria ha effettivamente bisogno di salvare il suo stato.

UPDATE

Nella vostra ActivityonSaveInstanceState e onRestoreInstanceState, è provare a salvare Fragment riferimenti e poi ripristinarli con qualcosa di simile:

public void onSaveInstanceState(Bundle outState){ 
    getFragmentManager().putFragment(outState,"myfragment",myfragment); 
} 
public void onRestoreInstanceState(Bundle inState){ 
    myFragment = getFragmentManager().getFragment(inState,"myfragment"); 
} 

Dimmi poi se si ha la fortuna! :-)

+0

Allora cosa dovrei fare? Dovrei chiamare il onSaveInstanceState del frammento dal onSaveInstanceState dell'attività? –

+0

Un UPDATE per te nella risposta. –

+0

ok ... quindi onSaveInstanceState per i frammenti è praticamente inutile. Almeno, per i frammenti (transazioni frammentate) che si trovano nello stack posteriore. –

0

Imposta l'impostazione setRetainInstance nella guida dei frammenti. provare

+0

Se il frammento viene utilizzato per lo scopo dell'interfaccia utente, non impostare mai 'setRetainInstance' su' true'! – matusalem

5

Costruire su Jorge Gil - 'risposta xil xɔɾ.xɛ notare quanto segue:

  • non dimenticare chiamare le implementazioni eccellenti di onSaveInstanceState() e onRestoreInstanceState().
  • Se si utilizza il pacchetto di supporto: utilizzare getSupportFragmentManager() anziché getFragmentManager().
  • Quando recuperi il tuo frammento originale devi lanciarlo.

Mi spiace di essere capitano ovvio!

0

Penso che la soluzione corretta sia quella di leggere quelle variabili membro da savedInstanceState in onCreate che sembra essere chiamato sempre prima dello onSaveInstanceState. Se si elaborano i campi in onViewCreated, essi non hanno la possibilità di essere inizializzati prima del prossimo onSaveInstanceState (in questo caso speciale, quando Frammento si trova nel backstack).

Problemi correlati