2014-11-06 12 views
5

Che cos'è esattamente una situazione di "perdita di stato"? puoi dimostrare uno scenario completo (includi del codice) che lo causerà? Ho letto molti tutorial (ufficiali e non ufficiali), blog, stackoverflow domande/risposte sull'argomento ma mai così un esempio che causerà una reale perdita di stato e che cosa succede dopo che si è verificata la perdita di stato.Perdita di stato del frammento?

Non conosco i passaggi completi da eseguire per causare una perdita di stato. Quello che ho cercato di fare è:

  1. Un'attività con un layout che contiene un layout di cornice.
  2. Un frammento che presenta un layout con un testo "Ciao" all'interno di TextView.
  3. Il frammento viene aggiunto con una transazione di frammento al layout di cornice sopra.
  4. Uno scenario in cui l'utente preme il pulsante home e quindi si verifica una transazione di frammento che viene eseguita utilizzando il metodo commitAllowingStateLoss().

Poi ho provato a fare un cambio di configurazione ma tutto era ok. Poi ho provato a riprendere dallo sfondo ma anche tutto era ok. Poi ho provato ad aggiungere il frammento allo stack posteriore e fare il commitAllowingStateLoss() e poi i passaggi precedenti, ma quando si verifica la modifica della configurazione o quando sono tornato dallo sfondo, e quindi ho premuto il pulsante Indietro che ha rimosso la transazione, che significa rimuovere il frammento dallo stack posteriore, il che significa che non si verificano perdite di stato.

Quindi cos'è esattamente questa "perdita di stato"? in che modo influisce su ciò che l'utente vedrà sullo schermo. puoi mostrare uno scenario di perdita di stato completo?

EDIT: mettere un po 'codice di prova: il codice

attività:

package com.example.statelosstest; 

import android.app.Activity; 
import android.app.FragmentTransaction; 
import android.os.Bundle; 
import android.os.Handler; 

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 

    //Just for test 
    Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() { 

     @Override 
     public void run() { 
      addDummyFragment();    
     } 
    }, 5000); 
} 

/** 
* Invoke this method after onSaveInstanceState has been called, 
* for example after user press android home button. 
*/ 
private void addDummyFragment(){ 
    DummyFragment frag = new DummyFragment(); 
    FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
    transaction.add(R.id.fragment_frame, frag, frag.getClass().getName()); 

    // tried this also 
    // transaction.addToBackStack(frag.getClass().getName()); 

    transaction.commitAllowingStateLoss(); 
} 

} 

EDIT: ancora nessuna risposta -
ho cercato di simulare le cose che ho pensato che causerà una perdita di stato e che Vedrò quella perdita di stato nell'interfaccia utente ma non potrei simulare o causare alcuna situazione di perdita di stato. Per favore qualcuno può mostrare uno scenario in cui si verifica una perdita di stato e che può essere visto nell'interfaccia utente, il che significa che la perdita di stato si verifica effettivamente quando si verifica un comportamento imprevisto.

+0

Vedi anche: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html –

+0

Ottimo articolo, ma l'ho letto già prima (più di una volta). Non vi è alcun esempio di perdita di stato reale e cosa accade realmente quando si verifica una perdita di stato. Non riesco a immaginare perché è pericoloso usare commitAllowingStateLoss()? Non riesco a immaginare una situazione in cui inciderà davvero sul mio codice. Puoi mostrare un codice e uno scenario che si tradurrà in un comportamento strano dell'interfaccia utente a causa di commitAllowingStateLoss() che ovviamente verrà utilizzato dopo che onSaveInstanceState() è stato chiamato – Elizabeth

+0

@Alex Lockwood sei la mia ultima speranza;) per risolvere questo problema. – Elizabeth

risposta

3

Alcuni esempi di perdita di stato:

1. supporre u hanno un pulsante e un TextView. nel codice, è stato definito un intero i con valore iniziale 0 che aumenta di uno per il pulsante cicking e il suo valore viene visualizzato nella vista testo. supponiamo che tu abbia premuto il pulsante 5 volte, quindi la visualizzazione testuale sarà impostata su 0. Questo è Il numero intero ha perso il suo valore sullo schermo.

Soluzione: eseguire l'override di onSaveInstanceState e inserire il valore del numero intero. quindi conservare il valore di tale numero intero nel metodo onResume o onCreate.

2. Considerate che avete una lista di cose da fare. L'utente aggiunge a dos in quella listview in modo dinamico. supponiamo che l'utente abbia aggiunto 3 elementi, quindi ruotato sullo schermo (o se l'app si riavvia), il listview diventerà vuoto.

Soluzione: Sempre in onSaveInstanceState, inserire ArrayList. (Le liste possono essere implementate come "Serializabe" o "Parcelable" e possono essere archiviate nel loro insieme. Non è necessario memorizzare ogni voce di listview). quindi nel metodo onResume o onCreate, ottieni quella listview.

3. Tutti gli edittexts nella schermata si svuotano quando lo schermo ruota.

Quello che ho capito della perdita di stato in un linguaggio semplice è che ogni volta che la configurazione cambia (rotazione dello schermo o riavvio dell'app), viene chiamato l'intero ciclo di vita dell'attività. Quindi, qualunque cosa fosse lì che non è stata salvata andrà persa.

Bene, questo mi ricorda il messaggio di uscita della schermata di Nintendo, "Qualsiasi cosa non salvata andrà persa".

+0

Quello che hai descritto è molto buono, ma lo so già. La mia domanda riguardava la perdita dello stato dei frammenti e riguardava specificamente una transazione che può accadere dopo che è stato chiamato onSaveInstanceState. Ad esempio: inviando una richiesta http e mentre attende la risposta, l'utente fa clic sul pulsante home e successivamente arriva la risposta e si verifica una transazione frammentata. Ho messo qualche codice in questione. – Elizabeth

+0

se ho capito bene, quello che vuoi è fare qualcosa in onSaveInstanceState (ricevere la richiesta http mentre l'utente è assente). potrei sbagliarmi ma quello che la mia logica dice è che dopo i metodi onSaveInstanceState, onPause, vengono chiamati i metodi onDestroys. Quindi un frammento che è stato messo in pausa (o distrutto o staccato) non può fare nulla. Puoi usare asynctask invece di fare roba in background –

+0

e su backstack, non significa che il frammento sia vivo sullo sfondo. anche se hai usato il backstack per effettuare transazioni tra i frammenti, verrà chiamato il suo onPause e tutti quei metodi. Significa solo che puoi tornare a questo frammento premendo il pulsante Indietro dal prossimo frammento (o qualsiasi altro frammento.), Dipende da come hai usato il pulsante Indietro) –

Problemi correlati