Począwszy od dokumentacji:
public void setRetainInstance (boolean retain)
Kontroluj, czy instancja fragmentu jest zachowywana podczas ponownego tworzenia działania (na przykład po zmianie konfiguracji). Można tego używać tylko z fragmentami, których nie ma na tylnym stosie. Jeśli jest ustawiony, cykl życia fragmentu będzie nieco inny po odtworzeniu działania:
- onDestroy () nie będzie wywoływany (ale nadal będzie onDetach (), ponieważ fragment jest odłączany od bieżącej aktywności).
- Program onCreate (pakiet) nie zostanie wywołany, ponieważ fragment nie jest ponownie tworzony.
- onAttach (Activity) i onActivityCreated (Bundle) będą nadal wywoływane.
Mam parę pytań:
Czy fragment również zachowuje swój widok, czy też zostanie odtworzony po zmianie konfiguracji? Co dokładnie oznacza „zachowane”?
Czy fragment zostanie zniszczony, gdy użytkownik opuści działanie?
Dlaczego nie działa z fragmentami na tylnym stosie?
Jakie są przypadki użycia, w których warto zastosować tę metodę?
Odpowiedzi:
Przede wszystkim sprawdź mój post na temat zachowanych fragmentów. To może pomóc.
Teraz, aby odpowiedzieć na twoje pytania:
Tak,
Fragment
stan zostanie zachowany podczas zmiany konfiguracji. W szczególności „zachowane” oznacza, że fragment nie zostanie zniszczony w wyniku zmian konfiguracji. Oznacza to, żeFragment
zostaną zachowane, nawet jeśli zmiana konfiguracji spowodujeActivity
zniszczenie instrumentu bazowego .Podobnie jak
Activity
s,Fragment
s może zostać zniszczony przez system, gdy zasoby pamięci są niskie. To, czy Twoje fragmenty zachowają stan instancji w trakcie zmian konfiguracji, nie będzie miało wpływu na to, czy system zniszczy jeFragment
po opuszczeniuActivity
. Jeśli opuściszActivity
(tzn. Naciskając przycisk Home),Fragment
s może zostać zniszczony. Jeśli wyjdzieszActivity
, naciskając przycisk Wstecz (w ten sposób wywołującfinish()
i skutecznie niszczącActivity
), wszystkieActivity
dołączoneFragment
s zostaną również zniszczone.Prawdopodobnie jest wiele powodów, dla których nie jest obsługiwany, ale najbardziej oczywistym powodem jest to, że
Activity
zawiera odniesienie doFragmentManager
iFragmentManager
zarządza backstackiem. Oznacza to, że bez względu na to, czy zdecydujesz się zachować swoje,Fragment
czy nie,Activity
(i tym samymFragmentManager
backstack) zostanie zniszczony przy zmianie konfiguracji. Innym powodem, dla którego może nie działać, jest to, że sytuacja może stać się trudna, jeśli zarówno zachowane fragmenty, jak i niezarezerwowane fragmenty zostaną dopuszczone do istnienia na tym samym plecaku.Zachowane fragmenty mogą być bardzo przydatne do propagowania informacji o stanie - zwłaszcza zarządzania wątkami - między instancjami działania. Na przykład fragment może służyć jako host dla instancji
Thread
lubAsyncTask
, zarządzając jego działaniem. Zobacz mój post na blogu na ten temat, aby uzyskać więcej informacji.Ogólnie potraktowałbym to podobnie do używania
onConfigurationChanged
zActivity
... nie używaj go jako bandaida tylko dlatego, że jesteś zbyt leniwy, aby poprawnie wdrożyć / obsłużyć zmianę orientacji. Używaj go tylko wtedy, gdy potrzebujesz.źródło
setRetainInstance(true)
,Fragment
obiekt java i cała jego zawartość nie są niszczone podczas obrotu, ale widok jest odtwarzany. To sięonCreatedView()
nazywa ponownie. Jest to w zasadzie sposób, w jaki powinien był działaćActivities
od Androida 1.0. Nie sądzę, aby korzystanie z niego było „leniwe” lub używanie go nie jest „właściwe”. W rzeczywistości nie rozumiem, dlaczego nie jest to ustawienie domyślne lub dlaczego miałbyś chcieć go wyłączyć.Fragment
s są zachowywane tylko podczas zmian konfiguracji, w których podstawowa aktywność ma zostać zniszczona i natychmiast odtworzona. We wszystkich innych przypadkach, w których aktywność jest niszczona, zachowane fragmenty również zostaną zniszczone.setRetainInstance(true)
jest używany, nadal trzeba zaimplementować własną trwałość (savedInstanceState
lub w inny sposób), aby móc obsłużyć wszystkie scenariusze: np. „Klucz domowy, obrót, powrót do aplikacji” odtwarza mój fragment z konstruktorem wywołanie, tracąc wszystkie zmienne stanu. MamAsyncTask
zmienną jako element członkowski, dlatego chcę ją zachować, teraz, jeśli chcę, aby działała, jestem zmuszony zatrzymać zadanie, zapisać stan i wznowić po powrocie użytkownika. Podsumowując, jest to szybki sposób na pomoc w rotacji, ale ogólnie bezużyteczny.setRetaininstance
jest przydatny tylko wtedy, gdy twojeactivity
zostanie zniszczone i ponownie utworzone z powodu zmiany konfiguracji, ponieważ instancje są zapisywane podczas połączenia zonRetainNonConfigurationInstance
. Oznacza to, że jeśli obrócisz urządzenie, zachowane fragmenty pozostaną na nim (nie zostaną zniszczone i ponownie utworzone), ale gdy środowisko wykonawcze zabije działanie w celu odzyskania zasobów, nic nie pozostanie. Kiedy naciśniesz przycisk Wstecz i wyjdziesz z działania, wszystko zostanie zniszczone.Zwykle używam tej funkcji do zapisywania zmiany orientacji czasu. Powiedzmy, że pobrałem kilka bitmap z serwera, a każda z nich ma 1 MB, gdy użytkownik przypadkowo obróci swoje urządzenie, na pewno nie chcę ponownie wykonywać całej operacji pobierania. Tworzę
Fragment
mapę bitową i dodam ją do menedżera i wywołaniasetRetainInstance
, wszystkie mapy bitowe nadal tam są, nawet jeśli zmieni się orientacja ekranu.źródło
mActivity
odniesienie dla ciebie. Ale nie wiem, czy środowisko wykonawcze wyczyści również widgety w instancji fragmentu w tym przypadku. Wypróbuj go lub zanurz się w kodzie źródłowym.SetRetainInstance (true) pozwala przetrwać fragmentowi. Jego elementy zostaną zachowane podczas zmiany konfiguracji, takiej jak rotacja. Ale nadal może zostać zabity, gdy aktywność zostanie zabita w tle. Jeśli aktywność zawierająca w tle zostanie zabita przez system, jego instancja powinna zostać zapisana przez system, który poprawnie obsługiwałeś w SaveSstainState. Innymi słowy, onSaveInstanceState będzie zawsze wywoływany. Chociaż onCreateView nie zostanie wywołany, jeśli SetRetainInstance ma wartość true, a fragment / aktywność nie jest jeszcze zabity, nadal będzie wywoływany, jeśli zostanie zabity i będzie próbował zostać przywrócony.
Oto kilka analiz aktywności / fragmentu Androida, które mogą pomóc. http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html
źródło
setRetainInstance () - Przestarzałe
Jako fragmenty Wersja 1.3.0-alpha01
źródło
setRetainInstance (boolean) jest przydatny, gdy chcesz mieć komponent niepowiązany z cyklem życia działania. Technika ta jest używana na przykład przez rxloader do „obsługi cyklu życia Androida dla Obxable rxjava's Observable” (który znalazłem tutaj ).
źródło