Cykl życia fragmentu

Każda instancja Fragment ma własny cykl życia. Gdy użytkownik porusza się po aplikacji i korzysta z niej, fragmenty kodu przechodzą przez różne stany w trakcie swojego cyklu życia w miarę ich dodawania, usuwania, a także otwierania lub zamykania ekranu.

Aby zarządzać cyklem życia, Fragment implementuje LifecycleOwner, udostępniając obiekt Lifecycle, do którego można uzyskać dostęp za pomocą metody getLifecycle().

Każdy możliwy stan Lifecycle jest reprezentowany w wyliczeniu Lifecycle.State.

Tworząc Fragment w oparciu o element Lifecycle, możesz wykorzystać dostępne techniki i klasy dotyczące postępowania z cyklami życia z użyciem komponentów uwzględniających cykl życia. Możesz na przykład wyświetlić lokalizację urządzenia na ekranie za pomocą komponentu identyfikującego cykl życia. Ten komponent może automatycznie rozpocząć nasłuchiwanie, gdy fragment stanie się aktywny, i zatrzymać, gdy fragment przejdzie w stan nieaktywny.

Zamiast używać LifecycleObserver, klasa Fragment zawiera metody wywołania zwrotnego, które odpowiadają każdej zmianie w cyklu życia fragmentu. Są to między innymi: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy().

Widok danego fragmentu ma osobny element Lifecycle, którym zarządza się niezależnie od jego elementu Lifecycle. Fragmenty utrzymują w swoim widoku element LifecycleOwner, do którego można uzyskać dostęp za pomocą getViewLifecycleOwner() lub getViewLifecycleOwnerLiveData(). Dostęp do Lifecycle widoku jest przydatny w sytuacjach, gdy komponent zależny od cyklu życia powinien działać tylko wtedy, gdy istnieje widok fragmentu, na przykład obserwować LiveData, który ma być wyświetlany tylko na ekranie.

W tym temacie szczegółowo omówiono cykl życia elementu Fragment, wyjaśniamy niektóre reguły, które określają stan cyklu życia fragmentu, i pokazujemy związek między stanami Lifecycle a wywołaniami zwrotnymi cyklu życia fragmentu.

Fragmenty i menedżer fragmentów

Po utworzeniu fragmentu zaczyna się on od stanu INITIALIZED. Aby fragment mógł przejść przez resztę cyklu życia, musisz go dodać do FragmentManager. Element FragmentManager odpowiada za ustalenie, w jakim stanie powinien się znajdować jego fragment, a następnie za jego przeniesienie do tego stanu.

Poza cyklem życia fragmentu FragmentManager odpowiada też za dołączanie fragmentów do aktywności hosta i odłączanie ich, gdy fragment nie jest już używany. Klasa Fragment ma 2 metody wywołań zwrotnych: onAttach() i onDetach(), które możesz zastąpić, aby wykonać zadanie, gdy wystąpi jedno z tych zdarzeń.

Wywołanie zwrotne onAttach() jest wywoływane, gdy fragment został dodany do elementu FragmentManager i jest dołączony do jego aktywności hosta. W tym momencie fragment jest aktywny, a element FragmentManager zarządza swoim stanem cyklu życia. W tym momencie metody FragmentManager, takie jak findFragmentById(), zwracają ten fragment.

Funkcja onAttach() jest zawsze wywoływana przed każdą zmianą stanu cyklu życia.

Wywołanie zwrotne onDetach() jest wywoływane, gdy fragment zostanie usunięty z elementu FragmentManager i odłączony od jego aktywności hosta. Fragment nie jest już aktywny i nie można go pobrać za pomocą findFragmentById().

onDetach() jest zawsze wywoływana po każdej zmianie stanu cyklu życia.

Pamiętaj, że te wywołania zwrotne nie są powiązane z metodami FragmentTransaction attach() i detach(). Więcej informacji o tych metodach znajdziesz w artykule Transakcje związane z fragmentem.

Stany cyklu życia fragmentu i wywołania zwrotne

Podczas określania stanu cyklu życia fragmentu, FragmentManager bierze pod uwagę te kwestie:

  • Maksymalny stan fragmentu jest określany przez jego FragmentManager. Fragment nie może przejść poza stan FragmentManager.
  • W ramach FragmentTransaction możesz ustawić maksymalny stan cyklu życia fragmentu za pomocą funkcji setMaxLifecycle() .
  • Stan cyklu życia fragmentu nigdy nie może być wyższy niż jego element nadrzędny. Na przykład fragment nadrzędny lub działanie muszą być rozpoczęte przed jego fragmentami podrzędnymi. Podobnie fragmenty podrzędne należy zatrzymać przed ich fragmentem nadrzędnym lub działaniem.
stany cyklu życia fragmentu i ich relację, wywołania zwrotne cyklu życia fragmentu i cykl życia widoku fragmentu
Rysunek 1. Stany fragmentu Lifecycle i ich związek z wywołaniami cyklu życia fragmentu i jego widokiem Lifecycle.

Rysunek 1 przedstawia każdy stan Lifecycle fragmentu i jego związek z wywołaniami zwrotnymi w cyklu życia fragmentu i widokiem Lifecycle danego fragmentu.

Wraz z etapem cyklu życia fragment przesuwa się w górę i w dół w kolejnych stanach. Na przykład fragment dodany na początku stosu wstecznego przesuwa się w górę z CREATED do STARTED do RESUMED. I odwrotnie, gdy fragment zostanie wysunięty z tylnego stosu, przesuwa się w dół przez te stany, w kierunku od RESUMED do STARTED do CREATED, a na koniec do DESTROYED.

Przejście stanu na wyższy

Przechodząc w górę przez stany cyklu życia fragment, najpierw wywołuje powiązane wywołanie zwrotne cyklu życia, aby uzyskać nowy stan. Po zakończeniu wywołania zwrotnego odpowiedni Lifecycle.Event jest wysyłany do obserwatorów przez parametr Lifecycle fragmentu, a po nim widok Lifecycle fragmentu, jeśli został utworzony.

UTWORZONO Fragment

Gdy fragment osiągnie stan CREATED, zostanie dodany do FragmentManager, a metoda onAttach() została już wywołana.

W tym miejscu warto przywrócić zapisany stan powiązany z samym fragmentem za pomocą metody SavedStateRegistry danego fragmentu. Zwróć uwagę, że widok fragmentu nie został jeszcze utworzony, a każdy stan powiązany z widokiem fragmentu powinien zostać przywrócony dopiero po jego utworzeniu.

To przejście wywołuje wywołanie zwrotne onCreate(). Wywołanie zwrotne odbiera też argument savedInstanceState Bundle zawierający dowolny stan zapisany wcześniej przez onSaveInstanceState(). Pamiętaj, że przy pierwszym tworzeniu fragmentu savedInstanceState ma wartość null, ale przy kolejnych rekreacjach zawsze ma ona wartość niezerową, nawet jeśli nie zastąpisz onSaveInstanceState(). Więcej informacji znajdziesz w sekcji Zapisywanie stanu z fragmentami.

UTWORZONO Fragment i wyświetl zainicjowany

Widok Lifecycle fragmentu jest tworzony tylko wtedy, gdy Fragment zapewnia prawidłową instancję View. W większości przypadków możesz używać konstruktorów fragmentów, które pobierają @LayoutId, co automatycznie powiększy widok w odpowiednim momencie. Możesz też zastąpić parametr onCreateView(), aby automatycznie zwiększać rozmiar lub utworzyć widok fragmentu.

Jeśli widok fragmentu jest utworzony z wartością inną niż zero View, tag View jest ustawiony na fragmencie i można go pobrać za pomocą funkcji getView(). Następnie w getViewLifecycleOwnerLiveData() pojawia się nowa wartość INITIALIZED LifecycleOwner odpowiadająca widokowi fragmentu. W tej chwili jest też wywoływane wywołanie zwrotne cyklu życia onViewCreated().

Tutaj możesz ustawić początkowy stan widoku, rozpocząć obserwację wystąpień LiveData, których wywołania zwrotne powodują aktualizację widoku fragmentu, oraz skonfigurować adaptery w dowolnych instancjach RecyclerView lub ViewPager2 w widoku fragmentu.

UTWORZONO Fragment i widok

Po utworzeniu widoku fragmentu przywracany jest poprzedni stan widoku (jeśli występował), a jego element Lifecycle zostaje przeniesiony do stanu CREATED. Właściciel cyklu życia widoku wysyła też zdarzenie ON_CREATE swoim obserwatorom. Tutaj należy przywrócić dowolny dodatkowy stan powiązany z widokiem fragmentu.

To przejście wywołuje też wywołanie zwrotne onViewStateRestored().

Fragment i widok: START

Zdecydowanie zalecamy powiązanie komponentów dopasowanych do cyklu życia ze stanem STARTED fragmentu, ponieważ ten stan gwarantuje, że widok fragmentu jest dostępny, o ile został utworzony, i że można bezpiecznie wykonać FragmentTransaction na podrzędnym elemencie FragmentManager danego fragmentu. Jeśli widok fragmentu nie ma wartości null, widok fragmentu (Lifecycle) jest przenoszony do STARTED tuż po przeniesieniu jego Lifecycle do STARTED.

Gdy fragment zmieni się na STARTED, wywoływane jest wywołanie zwrotne onStart().

Fragment i widok WZNÓW

Gdy fragment jest widoczny, wszystkie efekty Animator i Transition zostały zakończone, a fragment jest gotowy do interakcji z użytkownikiem. Lifecycle fragmentu przechodzi do stanu RESUMED i jest wywoływane wywołanie zwrotne onResume().

Przejście na RESUMED jest odpowiednim sygnałem, że użytkownik może teraz wchodzić w interakcję z Twoim fragmentem. W przypadku fragmentów, które nie są obiektem RESUMED, nie należy ręcznie koncentrować się na swoich widokach ani próbować obsługiwać widoczności metody wprowadzania.

Przejścia w dół

Gdy fragment przesuwa się w dół do niższego stanu cyklu życia, odpowiednia wartość Lifecycle.Event jest wysyłana obserwatorom przez widok Lifecycle fragmentu (jeśli został utworzony), a po nim następuje Lifecycle fragmentu. Po wysłaniu zdarzenia cyklu życia fragment ten wywołuje powiązane wywołanie zwrotne cyklu życia.

Fragment i widok: START

Gdy użytkownik zacznie opuszczać fragment, a jego fragment będzie nadal widoczny, parametry Lifecycle tego fragmentu i jego widoku są przenoszone z powrotem do stanu STARTED i wysyłają zdarzenie ON_PAUSE swoim obserwatorom. Następnie fragment wywołuje wywołanie zwrotne onPause().

UTWORZONO Fragment i widok

Gdy fragment przestanie być widoczny, parametry Lifecycle tego fragmentu i jego widoku są przenoszone do stanu CREATED i wysyłają zdarzenie ON_STOP swoim obserwatorom. Przejście tego stanu jest aktywowane nie tylko przez zatrzymywane działanie nadrzędne lub fragment, ale także przez zapisanie stanu przez tę aktywność lub fragment. To zachowanie gwarantuje, że zdarzenie ON_STOP jest wywoływane przed zapisaniem stanu fragmentu. Sprawia to, że zdarzenie ON_STOP będzie ostatnim punktem, w którym można bezpiecznie wykonać FragmentTransaction na podrzędnym FragmentManager.

Jak widać na rysunku 2, kolejność wywołania zwrotnego onStop() i zapisywanie stanu za pomocą onSaveInstanceState() różni się zależnie od poziomu interfejsu API. W przypadku wszystkich poziomów interfejsu API starszych niż API 28 obiekt onSaveInstanceState() jest wywoływany przed onStop(). W przypadku interfejsów API na poziomach 28 i wyższych kolejność wywołań jest odwrócona.

wywoływanie różnic w kolejności wywołań funkcji onStop() i onSaveInstanceState()
Rysunek 2. Różnice w kolejności wywołań dla onStop() i onSaveInstanceState().

UTWORZONO i wyświetl Zniszczony fragment

Po zakończeniu animacji i przejścia wyjścia i odłączeniu widoku fragmentu od okna widok Lifecycle fragmentu zostaje przeniesiony do stanu DESTROYED i wysyła zdarzenie ON_DESTROY swoim obserwatorom. Następnie fragment wywołuje wywołanie zwrotne onDestroyView(). W tym momencie widok fragmentu osiągnął koniec cyklu życia i getViewLifecycleOwnerLiveData() zwraca wartość null.

Na tym etapie należy usunąć wszystkie odniesienia do widoku fragmentu, aby umożliwić zbieranie śmieci.

Zniszczony fragment

Jeśli fragment zostanie usunięty lub FragmentManager zostanie zniszczony, element Lifecycle fragmentu zostanie przeniesiony do stanu DESTROYED i wyśle zdarzenie ON_DESTROY do swoich obserwatorów. Następnie fragment wywołuje wywołanie zwrotne onDestroy(). W tym momencie fragment osiągnął koniec cyklu życia.

Dodatkowe materiały

Więcej informacji o cyklu życia fragmentu znajdziesz w tych dodatkowych materiałach.

Przewodniki

Blogi