Zatwierdzanie transakcji we fragmentach Androida

Programując na system Android spotkałeś się z fragmentami. W jaki sposób zatwierdzałeś zmiany we fragmentach? Czy na pewno robiłeś to właściwie? Zatwierdzanie transakcji we fragmentach nie jest takie proste ponieważ klasa FragmentTransaction w bibliotece pomocy udostępnia aż cztery metody. Zobaczmy jakie one są.

Co to jest FragmentTransaction?

Klasa FragmentManager zarządza fragmentami w Androidzie. Korzystając z fragmentów można wykonać pewne działanie w wyniku interakcji z użytkownikiem. Należą do nich dodawanie, usuwanie, zastępowanie poszczególnych elementów. Wszystkie te zmiany stanowią kolekcję, zbiór ten nazywa się transakcją. Aby zarządzać zmianami we fragmentami korzystamy właśnie z FragmentTransaction.

Poznaj braci: Commit() i CommitAllowingStateLoss()

Zatwierdzanie transakcji we fragmentów możesz wykonać za pomocą: commit() i CommitAllowingStateLoss() są to metody bardzo podobne do siebie. Obie metody planują zmiany. Zatwierdzenie nie następuje natychmiast, zostanie zaplanowane i wykonana gdy główny wątek będzie gotowy. Jaka jest różnica? Korzystając z commit() musisz uważać na wyjątek IllegalStateException, który mówi, że nie można wykonać commit() po onSaveInstanceState().

Uzupełnij wiedzę o: Weryfikacja SMS w aplikacji Android

Gdy wywołasz metodę commit() to FragmentManager sprawdza, czy już zapisał swój stan. Jeśli już zapisał swój stan, rzuci wyjątek IllegalStateException. Jeśli wywołasz commitAllowingStateLoss() po onSaveInstanceState() to, możesz stracić stan w menadżerze fragmentów i co za tym idzie status jakichkolwiek dodanych lub usuniętych fragmentów od onSaveInstanceState(). Zobaczmy przykład.

  1. Aplikacja wyświetla Fragment A.
  2. Użytkownik nacisnął przycisk „Ekran główny”. Twoja aplikacja przechodzi na drugi plan. Wywoływana jest metoda onStop() i onSaveInstanceState().
  3. Teraz Twoja aplikacja dostała informacje zwrotne, na przykład udało się pobrać nowe dane z internetu, W tym celu musisz zamienić fragment A na fragment B i wywołujesz przy tym commitAllowingStateLoss(). Pamiętaj, że Twoja aplikacja nie jest na pierwszym planie.

Co teraz się stanie jeśli użytkownik wróci do aplikacji? Mamy dwie możliwości:

  • jeśli system zabił Twoją aplikację to użytkownik zobaczy fragment A, czyli będzie w punkcie 2,
  • jeśli system nie musiał zabijać aplikacji – zostanie wyświetlony fragment B. Następnym razem, gdy aplikacja zostanie zatrzymane, stan będzie już posiadał Fragment B.

Co się stanie jeśli wywołasz commitAllowingStateLoss() gdy aplikacja jest wznawiana? W takim przypadku zachowa się dokładnie tak, jakbyś korzystał z commit(). Stan zostanie zachowany, a Fragment zostanie odtworzony, nawet jeśli proces zostanie zabity.
A co z DialogFragment? Nie ma sensu korzystania z commitAllowingStateLoss() ponieważ DialogFragment posiada już odpowiednią metodę do obsługi stanu dismissAllowingStateLoss(). Chyba, że chcesz ręcznie zatwierdzać transakcje we fragmentach, wtedy to ma sens.

Poznaj siostry commitNow() i commitNowAllowingStateLoss()

Oprócz wymienionych wyżej metod mamy jeszcze dwie, które zatwierdzają transakcje we fragmentów w Androidzie:

Jaka jest między nimi różnica? Łatwo się domyślić, te metody w stosunku do poprzednich są wykonywane od razu. W końcu kobiety mają pierwszeństwo 😉 Metoda commitNow() zapobiega przypadkowemu uruchomieniu większej liczby transakcji niż faktycznie chcesz wykonać. Pamiętaj, że commitNow() nie można używać z addToBackStack(). Natomiast jest odpowiednik  popBackStackImmediate() – działa synchronicznie.

Uzupełnij wiedzę o: Ikony FontAwesome w Androidzie

Dla commitNowAllowingStateLoss() jest alternatywa w postaci executePendingTransactions(), która nie tylko wykonuje bieżące transakcje, ale także oczekujące.

Co wybrać?

Podsumujmy w jaki sposób możesz zatwierdzać transakcje we fragmentach:

  • jeśli wykonujesz wiele transakcji i nie dodajesz transakcje do stosu, powinieneś używać commit() lub commitNow(),
  • użyj executePendingTransactions(), jeśli chcesz upewnić się, że zestaw transakcji ma wykonać się w określonym momencie,
  •  jeśli zatwierdzanie transakcji fragmentów w Androidzie nie jest krytyczna (np. Dialog, który może być ponownie uruchomiony przez użytkownika) to warto skorzystać z commitAllowingStateLoss()
  • niektóre aplikacje wylogowują użytkownika lub powracają na ekran główny po tym, jak proces został zabity. W takim przypadku używanie commitAllowingStateLoss() dla wszystkich transakcji (od asynchronicznych wywołań zwrotnych) jest dobrym wyborem,

O co chodzi z tym błędem IllegalStateException?

Alex Lockwood opisał to świetnie na swoim blogu.

Podsumowanie

Fragmenty są często stosowane w aplikacjach mobilnych. Nie sztuką jest ich umieszczenie w kodzie, ale odpowiednie zarządzanie nimi. Mam nadzieje, że ten wpis rozwiał Twoje wątpliwości odnośnie zatwierdzania transakcji w Androidzie. Jak zawsze musisz przeprowadzać testy i przewidzieć zachowanie użytkownika, aby nie stracić kluczowych elementów.

Co dalej?

  • Polub stronę MYENV na Facebooku oraz śledź mnie na Twitterze
  • Zachęcam do komentowania i pisania propozycji tematów, o których chcesz przeczytać
  • Poleć ten wpis za pomocą poniższych przycisków. Będę Ci za to bardzo wdzięczny 🙂
  • Życzę Ci miłego dnia i miłego kodowania 🙂