2014-10-14 6 views
27

Czytam ListFragment kod źródłowego i widzę ten realizacji:onDestroyView ustawić Null praktyki aktywności za onDestroy/fragment za

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(); 
} 

w tej funkcji, programiści Google ustawić Null wszystkim widok pola, które deklarowanych w ListFragment i usuń oddzwanianie "mRequestFocus".

W ListActivity kod źródłowy. Programiści Google wdrożone jak poniżej:

protected ListAdapter mAdapter; 
protected ListView mList; 

private Handler mHandler = new Handler(); 


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

nie widzę programiści Google ustawić Null do mList na onDestroy z ListActivity jak zrobili dla klasy ListFragment.

Moje pytanie brzmi:

  1. Dlaczego programiści Google didnot ustawić Null do mList w onDestroy z ListActivity? Jakieś powody?

  2. Czy musimy ustawić wartość Null dla wszystkich pól widoku w działaniu onDestroy i onDestroyView działania?

3. Wszelkie praktyki SET NULL w tych dwóch funkcji: onDestroy Działania związane i fragment za onDestroyView?

Dziękujemy za pomysły!

Odpowiedz

45

Powodem, dla którego różnią się one od Fragmentów i Aktywności, jest to, że ich cykle życia są różne. Kiedy zniszczona zostaje Activity, znika na dobre. Jednak Fragments może wielokrotnie tworzyć i niszczyć swoje widoki, zanim zostaną faktycznie zniszczone. Dla wyjaśnienia, w działalność:

onDestroy() 
onCreate() 

nigdy nie nastąpi w ciągu do tej samej instancji Aktywny. Przez Fragment następujące jest całkowicie poprawny:

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

jeden przypadek, w którym można zobaczyć to, gdy Fragment idzie do tyłu stosu. Jego widok zostanie zniszczony (ponieważ nie jest już widoczny), ale instancja pozostanie w pobliżu, aby można je było łatwo wznowić, gdy użytkownik naciśnie przycisk, aby powrócić do niego (w którym to momencie ponownie zostanie wywołany numer onCreateView()).

Po onDestroyView() możesz (i najprawdopodobniej powinieneś) wypuścić wszystkie swoje referencje View, aby umożliwić ich zbieranie śmieci. W wielu przypadkach nie jest to konieczne, tak jak dzieje się to podczas zmiany konfiguracji, natychmiast nastąpi i cała instancja zostanie zebrana.

Zasadniczo chciałbym wypuścić wszystkie odniesienia do widoków w onDestroyView() i zaoszczędzić sporo pamięci, jeśli aplikacja ma duży backstack.

+0

Bardzo dobrze wyjaśnij. Mam pytanie. Dlaczego deweloperzy Google nie ustawili wartości Null na mAdapter w onDestroyView na liście ListFragment. Ustawienie pola Null na inne niż ui, takie jak mAdapter, jest niepotrzebne? –

+1

To dobre pytanie. Zazwyczaj nie ma to znaczenia, ale adaptery zwykle zawierają również odniesienie do kontekstu działania. Przypuszczam, że jest to zgodne z umową metody, która jest "onDestroyVIEW", więc niszczą tylko odniesienia do widoku. Myślę, że byłoby to nieoczekiwane zachowanie, gdybyś nazwał 'setListAdapter()', a następnie nazwałbyś 'getListAdapter()' i jest niewytłumaczalnie 'null'. Ponieważ adapter nie jest drogim obiektem do trzymania (z wyjątkiem przypadku setRetainInstance(), gdy może przeciekać działanie), nie ma wiele korzyści z jego zwolnieniem. – kcoppock

+0

Zastanawiam się więc, czy jest to lepsze podejście do rozpinania w oncreateview tuż przed związaniem? – j2emanue

0

Nie trzeba ustawiać wartości null, jeśli nie ma to wpływu na logikę aplikacji. Na przykład. if (mList == null) ...

+0

Co powiecie na wyciekanie pamięci Jeśli nie ustawię wartości Null? –

+0

Jest to niemożliwe, ponieważ wszystkie odniesienia pod obiektem fragmentu, co oznacza, że ​​raz obiekt fragmentu jest poza, wszystkie widoki i inne na zewnątrz. –

+1

@VladimirLichonos Jest to bardzo możliwe, szczególnie jeśli Fragment ma ustawioną opcję 'setRetainInstance (true)'. Jeśli zachowasz te odniesienia do widoków, możesz łatwo przeciekać instancję działania (ponieważ widoki zachowują odniesienie do działania). – kcoppock

Powiązane problemy