2014-11-10 12 views
5

Possiedo un frammento di libreria di supporto che invia una chiamata di rete e recreate() l'attività principale quando riceve una risposta di rete specifica. Riesco a vedere che l'attività viene ricreata come posso vedere sono chiamati i numeri onCreate() e onDestroy().Frammenti non distrutti durante l'attività di recreate()

Ma dopo che l'attività è stata ricreata, il frammento è ancora lì e si è bloccato in un loop che continua a ricreare e creare nuovi frammenti.

Ecco parte del onCreate() dell'attività:

if (someLogic()) { 
     fragmentA = new FragmentA(); 
     FragmentUtil.addFragment(getSupportFragmentManager(), fragmentA); 
    } else { 
     fragmentB = new FragmentB(); 
     FragmentUtil.addFragment(getSupportFragmentManager(), fragmentB); 
    } 

Fragmenta è quella che fa la chiamata di rete, e FragmentB è il frammento che dovrebbe essere visualizzato dopo l'recreate(). Quando controllo l'elenco dei frammenti con getSupportFragmentManager().getFragments(), vedo 1 istanze di FragmentA e 16 istanze di FragmentB.

La mia domanda è: perché succede e come risolverlo?

+0

Puoi mostrare come aggiungi i frammenti e ricreare l'attività? La mia ipotesi è che è necessario rimuovere fragmentA prima di riavviare l'attività, ma avrei bisogno di vedere il codice. A proposito, perché non sostituisci semplicemente fragmentA con fragmentB invece di riavviare l'attività? –

+0

Non è una risposta concreta o è la soluzione ideale ma è possibile controllare lo stack dei frammenti e aggiungere un nuovo frammento se necessario, altrimenti è possibile sostituire/aggiornare il frammento corrente – zgc7009

risposta

9

La chiamata recreate() causa essenzialmente lo spostamento di Activity in una modifica di configurazione. Una modifica alla configurazione fa sì che sias sia distrutto e ricreato sia Activity. Pertanto, i tuoi Fragment dovrebbero essere distrutti quando ciò si verifica (puoi vedere tu stesso aggiungendo un messaggio Log nel metodo onDestroy del tuo frammento).

Il fatto che le modifiche alla configurazione causano frammenti da distruggere e creare comunque non significa che il FragmentManager sarà semplicemente dimenticare i frammenti mai esistiti. Lo FragmentManager manterrà ancora un riferimento al frammento appena creato dopo che si è verificata la modifica della configurazione.

Una cosa si può fare per evitare che più frammenti vengano create è di fare qualcosa di simile in di vostra attività onCreate():

if (savedInstanceState == null) { 
    // The Activity is being created for the first time, so create and 
    // add new fragments. 
} else { 
    // Otherwise, the activity is coming back after being destroyed. 
    // The FragmentManager will restore the old Fragments so we don't 
    // need to create any new ones here. 
} 
+5

in modo esplicito per non conservare un frammento durante la ricreazione? Ho una configurazione del layout in modalità giorno/notte e ho alcuni problemi con più copie del frammento in memoria – spy

+0

@spy è possibile rimuovere il frammento manualmente prima di ricreare l'attività, "mFragmentManager.beginTransaction(). Remove (mFragment).();". – Xiaozou

1

avevo stessa situazione @spy scritto, ricreando la Activity dopo giorno/notte la modalità è cambiata. Activity aveva quattro Fragments che ottengono ripristinato dopo Activity.recreate() viene chiamato, perché FragmentManager li salva come @Alex Lockwood dichiarato. Ma ripristinare e non aggiungere Fragments dopo la ricreazione non mi aiuta a causa di alcune ragioni architettoniche del progetto, volevo che scomparissero.

soluzione è quella di eliminare Fragments da FragmentManager poco prima Activity.recreate() è chiamato, nel mio caso è in Activity.onStart():

FragmentManager fragmentManager = getSupportFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

Fragment fragmentA = fragmentManager.findFragmentByTag("fragmentATag"); 
if(fragmentA != null) 
    fragmentTransaction.remove(fragment); 
// Find and delete other Fragments 

fragmentTransaction.commit(); // or commitAllowingStateLoss() 

recreate(); 

In questo modo non sarà possibile ottenere Fragments ripristinato quando Activity.onCreate() si chiama.

Problemi correlati