2014-10-14 10 views
27

Ich lese ListFragment Quellcode und ich sehe diese Implementierung:Aktivität des onDestroy/Fragment des onDestroyView gesetzt Null Praktiken

ListAdapter mAdapter; 
ListView mList; 
View mEmptyView; 
TextView mStandardEmptyView; 
View mProgressContainer; 
View mListContainer; 
CharSequence mEmptyText; 
boolean mListShown; 

/** 
* Detach from list view. 
*/ 
@Override 
public void onDestroyView() { 
    mHandler.removeCallbacks(mRequestFocus); 
    mList = null; 
    mListShown = false; 
    mEmptyView = mProgressContainer = mListContainer = null; 
    mStandardEmptyView = null; 
    super.onDestroyView(); 
} 

In dieser Funktion Google-Entwickler eingestellt Null für alle Ansicht Felder, die in ListFragment erklärt und entfernen Rückruf 'mRequestFocus'.

In ListeActivity Quellcode. Google-Entwickler implementiert wie unten:

protected ListAdapter mAdapter; 
protected ListView mList; 

private Handler mHandler = new Handler(); 


@Override 
protected void onDestroy() { 
    mHandler.removeCallbacks(mRequestFocus); 
    super.onDestroy(); 
} 

ich nicht sehen Google-Entwickler MList auf onDestroy von ListActivity Null gesetzt, wie sie für ListFragment Klasse tat.

Meine Frage ist

  1. Warum Google-Entwickler MList in onDestroy von ListActivity Null gesetzt didnot? Irgendwelche Gründe?

  2. Müssen wir Null in alle View-Felder in Activity onDestroy und Fragment onDestroyView setzen?

3. Alle Verhaltensweisen für Satz Null in diesen beiden Funktionen: Aktivität des onDestroy und onDestroyView fragment?

Vielen Dank für Ihre Ideen!

Antwort

45

Der Grund, warum es zwischen Fragmenten und Aktivitäten unterschiedlich ist, ist, dass ihre Lebenszyklen unterschiedlich sind. Wenn ein Activity zerstört wird, geht es für immer weg. Fragments können jedoch ihre Ansichten mehrmals erstellen und zerstören, bevor sie tatsächlich zerstört werden. Zur Klarstellung in einer Aktivität:

onDestroy() 
onCreate() 

passieren wird nie in der Folge für die gleiche Aktivität Instanz. Für ein Fragment ist die folgende perfekt gültig:

onCreate() 
onCreateView() 
onDestroyView() 
onCreateView() 
onDestroyView() 
onDestroy() 

Ein Fall, in dem Sie das sehen kann, ist, wenn ein Fragment in den hinteren Stapel geht. Ihre Ansicht wird zerstört (da sie nicht mehr sichtbar ist), aber die Instanz bleibt bestehen, um leicht wieder aufgenommen zu werden, wenn der Benutzer zurückdrückt, um zu ihr zurückzukehren (zu diesem Zeitpunkt wird onCreateView() erneut aufgerufen).

Nach onDestroyView() können Sie (und wahrscheinlich sollten) alle Ihre View Referenzen freigeben, damit sie Garbage Collected gesammelt werden können. In vielen Fällen ist es nicht notwendig, als ob es gerade während einer Konfigurationsänderung passiert, onDestroy() wird sofort folgen und die gesamte Instanz wird Müll gesammelt werden.

Im Wesentlichen würde ich sagen, es ist gute Praxis, alle View-Referenzen in onDestroyView() freizugeben, und könnte einiges an Speicher sparen, wenn Ihre App einen großen Backstack hat.

+0

Sehr gut zu erklären. Ich habe eine Frage. Warum haben Google-Entwickler in OnDestroyView von ListFragment Null nicht auf mAdapter gesetzt? Setzen Sie Null auf Nicht-Ui-Feld wie mAdapter ist nicht notwendig? –

+1

Es ist eine gute Frage. In der Regel ist dies egal, aber Adapter enthalten auch einen Verweis auf einen Aktivitätskontext. Ich nehme an, es gilt für den Vertrag der Methode, die 'onDestroyVIEW' ist, also zerstören sie nur die View-Referenzen. Ich denke, es wäre ein unerwartetes Verhalten, wenn Sie 'setListAdapter()' aufrufen, und später rufen Sie 'getListAdapter()' auf und es ist unerklärlicherweise 'null'. Da ein Adapter kein teures Objekt ist, das er behalten kann (außer im Falle von setRetainInstance(), wenn er eine Aktivität verlieren könnte), hat die Veröffentlichung keinen großen Vorteil. – kcoppock

+0

Ich frage mich dann, ob es besser ist, in oncreateview zu lösen, bevor Sie binden? – j2emanue

0

Keine Notwendigkeit, null zu setzen, wenn dies die Logik der App nicht beeinflusst. Z.B. if (MList == null) ...

+0

Wie wäre es mit Speicherlecks Wenn ich Null nicht setze? –

+0

Es ist unmöglich, da alle Referenzen unter Fragment-Objekt, dh einmal Fragment-Objekt ist aus, alle Ansichten und andere auch heraus. –

+1

@VladimirLichonos Es ist sehr möglich, besonders wenn ein Fragment 'setRetainInstance (true)' gesetzt hat. Wenn Sie diese View-Referenzen beibehalten, könnten Sie leicht eine Activity-Instanz verlieren (da Views einen Verweis auf die Aktivität enthält). – kcoppock

Verwandte Themen