2016-07-25 11 views
32

Nowa metoda commitNow() dodana w Androidzie N i biblioteka obsługi wersji 24 ma ograniczoną i nieco mylącą dokumentację.W jaki sposób działa nowa wewnętrzna funkcja FragmentTransaction commitNow()?

Dokonuje synchronicznej transakcji. Wszelkie dodane fragmenty zostaną zainicjowane i całkowicie doprowadzone do stanu cyklu ich hosta , a wszystkie usunięte fragmenty zostaną zburzone odpowiednio przed zwróceniem tego połączenia. Zatwierdzenie transakcji w ten sposób pozwala na dodanie fragmentów jako dedykowanych, zamkniętych komponentów, które monitorują stan cyklu życia ich hosta, zapewniając jednocześnie bardziej stabilne zamawianie, gdy te fragmenty są w pełni zainicjowane i gotowe. Fragmenty, które zarządzają widokami, będą miały utworzone te widoki i zostaną dołączone.

Wywołanie commitNow korzystne jest wywołanie commit() następnie FragmentManager.executePendingTransactions() jako ostatniego będzie miał efekt uboczny usiłowanie popełnienia wszystkich aktualnie oczekujących transakcji, czy jest to pożądane zachowanie, czy nie.

Transakcje popełnione w ten sposób nie mogą być dodawane do tyłu stos FragmentManager, tak jak robi to złamie inny oczekuje gwarancje zamawianie innych asynchronicznie popełnionych transakcji. Ta metoda spowoduje zgłoszenie wyjątku IllegalStateException, jeśli transakcja poprzednio zażądała dodania jej do stosu tylnego za pomocą addToBackStack (String).

Transakcja może zostać zatwierdzona tylko tą metodą przed jej działalnością zawierającą zapisywanie jej stanu. Jeśli po tym punkcie zostanie podjęta próba zatwierdzenia , zostanie zgłoszony wyjątek. Dzieje się tak, ponieważ stan po zatwierdzeniu może zostać utracony, jeśli aktywność musi zostać przywrócona ze stanu. Zobacz commitAllowingStateLoss() dla sytuacji, w których może być w porządku utrata zatwierdzenia.

Podkreślono pogrubioną czcionką część, która według mnie jest myląca.

Więc moje główne problemy/pytania:

1 - nie mogą one zostać dodane? Mówi, że dostanę wyjątek IllegalStateException, więc czy będzie on lub nie zostanie dodany?

2 - Akceptuję fakt, że nie mogę tego użyć, jeśli chcemy dodać fragment w backstacku. Co nie znaczy, że masz ten wyjątek:

java.lang.IllegalStateException: This transaction is already being added to the back stack 

!!!! ????

Więc nie mogę zadzwonić pod numer addToBackStack(String), ponieważ wewnętrznie nazywa to dla mnie? Przykro mi, ale ... co? czemu? co, jeśli nie chcę, aby został dodany w backstacku? A jeśli spróbuję użyć tego fragmentu później, ale ponieważ NIE MOŻNA go dodać, później go nie ma?

Wygląda na to, że jest to coś, czego się spodziewam, gdy używałem commitAllowingStateLoss(), ale widzę, że commitNowAllowingStateLoss() również istnieje, więc ... jaki rodzaj logiki to następuje?

TL; DR

Jak commitNow() pracuje wewnętrznie dotyczące backstack?

+0

A teraz 5 miesięcy później, jeszcze nikt nie wie! – EpicPandaForce

+0

@EpicPandaForce odpowiedziałeś! Mam nadzieję, że moja odpowiedź Cię zadowoli :) –

+0

@NikoAdrianusYuwono Zyskuję nagrodę jeszcze trochę, aby się upewnić, ale to na pewno początek: p – EpicPandaForce

Odpowiedz

38

To dobrze, że kod źródłowy Androida to Open Source, gdy napotkaliśmy takie pytanie!

Odpowiedź

Więc rzućmy okiem na źródła BackStackRecord here

@Override 
public void commitNow() { 
    disallowAddToBackStack(); 
    mManager.execSingleAction(this, false); 
} 

@Override 
public FragmentTransaction disallowAddToBackStack() { 
    if (mAddToBackStack) { 
     throw new IllegalStateException(
       "This transaction is already being added to the back stack"); 
    } 
    mAllowAddToBackStack = false; 
    return this; 
} 

I mAddToBackStack zostanie ustawiony na true, jeśli zadzwonisz addToBackStack w transakcji.

Aby odpowiedzieć na twoje pytanie, nr addToBackStack nie jest wywoływany wewnętrznie po wywołaniu commitNow(), jest to komunikat wyjątkowy, który jest niejednoznaczny. Myślę, że powinno się powiedzieć: You're not allowed to add to backstack when using commitNow() zamiast aktualnej wiadomości.

Bonus:

Jeśli będziemy kopać głębiej FragmentManager kodu źródłowego here, commitNow() rzeczywiście robi prawie samo co executePendingTransactions() jak napisano wyżej, ale zamiast wykonywania wszystkich uprzednio popełnione transakcji commitNow() będzie popełnić wyłącznie tę transakcję .

Myślę, że to główny powód, dla którego commitNow() nie pozwala na dodanie do backstack, ponieważ nie może zagwarantować, że nie ma żadnych innych oczekujących transakcji. Jeśli commitNow() może dodać do backstacku, istnieje możliwość, że możemy złamać sekwencję backstack, która doprowadzi do niespodziewanej rzeczy.

+0

Najwyraźniej komunikat IllegalStateException jest po prostu niepoprawny ... Dzięki Niko! – Kaizie

+0

@Kaizie Serdecznie zapraszamy! Proszę przyjąć odpowiedź, jeśli uważasz, że jest poprawna :) –

+1

Tak, sprawdzając kod źródłowy, wygląda na to, że jest to poprawna odpowiedź. Ale jakoś czuję, że oversold ten nowy API w google IO ... ponieważ próbowali sprzedać go jako niesamowite rozwiązanie problemu IllegalStateException fragmentów po pauzie aktywności, ale jakoś to nie oferuje pełnych funkcji commit(), ponieważ nie możesz dodać go do backstacku ... więc można go używać tylko w określonych sytuacjach, jeśli twoja aplikacja pozwala na dodanie tego fragmentu bez dodawania go do backstacka ... W każdym razie poprawna odpowiedź! Dzięki! – Kaizie

Powiązane problemy