zrozum zachowanie startActivityForResult dla fragmentu i aktywności

cała aktywność startowa na skutek i na skutek działania jest dozwolona dwukierunkowa komunikacja między aktywnością źródłową a aktywnością docelową. Jego przepływ jest jak pokazano na poniższym schemacie.

z poniższego przepływu możemy łatwo zrozumieć przepływ OnActivityResult od aktywności źródłowej do aktywności docelowej

wywołanie aktywności źródłowej, startActivityForResult, wysyłając intencję wraz z kodem żądania do Android SDK.

Android SDK otwiera aktywność zgodnie z intencją.
gdy aktywność docelowa zakończy swoją pracę, powraca do aktywności rozmówcy.

może wysłać wynik z powrotem za pomocą setResult, wysyłając kod wyniku i intencję

kilka uwag tutaj:

kod wyniku jest używany przez aktywność docelową do oznaczania aktywności źródłowej, jaki jest jej status (np. OK, Anuluj itp.).

kod żądania jest używany przez aktywność źródłową, aby wiedzieć, która aktywność docelowa zwraca połączenie.

możemy zobaczyć, że aktywność docelowa nie ma widoczności kodu żądania.

nieudokumentowany przepływ fragmentu startActivityForResult

we fragmencie mamy również funkcję startActivityForResult do wywołania, a także funkcję onactivityresult do nadpisania.

to rodzi kilka pytań … np. Jak to działa? Czy jest to to samo, co początek aktywności na skutek i na skutek działania? Jak są spokrewnieni?
krótka odpowiedź jest taka, że są podobne, ale subtelnie różne. Częsta przyczyna zamieszania i bug. Ważne jest więc zrozumienie podobieństwa i różnic.

fragment przepływu ilustrowany.

Poniżej znajduje się schemat, który wyraźnie ilustruje, jak to wszystko działa razem. Różnice w przepływie activity forresult i onactivityresult są zabarwione na Czerwono.

omówmy to bardziej szczegółowo.

kiedy nazywamy startActivityForResult (Uwaga: Nie aktywność?.startActivityForResult), tworzenie aktywności docelowej jest takie samo. Jednak różnica polega na działalnościwynik.

startActivityForResult() onActivityForResult()

getActivity().startActivityForResult() musi obsługiwać go z activity’s onActivityForResult()

jeśli jesteś na fragment i chcesz obsłużyć wynik na fragment, użyj onActivityForResult(), w przeciwnym razie, jeśli chcesz obsłużyć go z activity fragmentu, użyj getActivity.startActivityForResult()

gdy Android SDK zwraca onActivityResult, kod żądania został zmieniony. 0xP0000 jest dołączany do oryginalnego kodu żądania.

wartość P zaczyna się od 1, A zwiększana dla każdego wyniku onActivityResult jest wywoływana z tego samego fragmentu docelowego. (Jeśli zostanie wywołany inny fragment docelowy, wartość p zostanie zresetowana).

np. jeśli oryginalny requestCode to 0xff (tj. 255), to requestCode zwraca po raz pierwszy 0x100ff. Drugi raz return requestCode będzie 0x200FF.

po powrocie do wyniku aktywności źródła oczekuje się, że powinien wywołać super.onActivityResult, który znajduje się w FragmentActivity (rodzic AppCompatActivity)

onActivityResult w FragmentActivity wyodrębni wartość P (używając requestCode >> 16). P jest indeksem tablicy, w której przechowywany jest fragment źródłowy. (np. jeśli requestCode to 0x200ff, to 0x200FF >> 16 = 2)

korzystając z wartości P, ma teraz dostęp do fragmentu źródłowego, który jest używany w kroku 9 poniżej.

teraz usuwa wartość p z requestCode (używając requestCode & 0xFFFF), aby wrócić do oryginalnego kodu żądania (np. jeśli requestCode wynosi 0x200FF, to 0x200FF & 0xFFFF = 0xff)

ponieważ teraz otrzymuje oryginalny kod żądania, który utworzony został fragment źródłowy, może wywołać wynik onactivityresult fragmentu źródłowego z oryginalnym kodem żądania.

kilka podstawowych punktów, które chcesz wiedzieć.

A. zachowanie funkcji startActivityForResult Activity różni się od funkcji Startactivityforresult fragmentu

we fragmencie, jeśli wywołamy activity?.startActivityForResult(...), wtedy funkcja onActivityResult fragmentu nie zostanie wywołana automatycznie.

B. Jeśli nadpisujemy wynik onActivityResult activity, upewnij się, że mamy super.onActivityResult w miejscu

jeśli nadpisujemy aktywność źródłową onActivityResult , ale zapominamy o super.onActivityResult, wtedy Fragment onActivityResult nie zostanie wywołany.

C. kod żądania widoczny w wyniku onactivityresult aktywności różni się od jednego fragmentu podanego

ze względu na powód, Android SDK dołączony P do requestCode, w aktywności onActivityResult nigdy nie dostaniemy tam identycznego requestCode. Czasami powoduje to zamieszanie dla programisty podczas debugowania kodu.

D. gdy aktywność zostanie przywrócona ze stanu (tj.= null), powinien unikać odtworzenia jego fragmentu.

po wywołaniu onActivityResult próbowano pobrać oryginalny fragment. Jest to również wykonywane dla aktywności, która jest przywracana ze stanu uśmierconego (np. emulowana za pomocą funkcji Don ’ t Keep Activity).

więc jeśli deweloper odtworzy Fragment za każdym razem, gdy OnCreate zostanie wywołany (niezależnie od tego, czy jest to przywrócony stan, czy nie), to oryginalny Fragment, który został przywrócony, zostanie zniszczony, a onActivityResult wywołującego, fragment w tajemniczy sposób nie zostanie wywołany.

jest to pułapka nawet dla wielu doświadczonych programistów i aplikacji wydanych w terenie, ponieważ jest to bardzo trudne do zidentyfikowanego błędu (ponieważ nie dzieje się to za każdym razem i wymaga bardziej złożonego przepływu do uruchomienia).

dzięki za przeczytanie…