Pochopit chování startActivityForResult pro Fragment a Aktivity
celý startActivityForResult a onActivityResult je povoleno 2-way komunikace mezi zdrojem aktivity a cíl aktivity. Jeho tok je znázorněn na následujícím obrázku.
Z níže tok, můžeme snadno pochopit tok OnActivityResult ze Zdroje Aktivity Cíl Aktivity
zdroj aktivity call, startActivityForResult zasláním v záměru spolu s žádostí kód na Android SDK.
Android SDK pak otevře aktivitu podle toho, jak je uvedeno v záměru.
jakmile Cílová aktivita dokončí svou úlohu, vrátí se k aktivitě volajícího.
To mohl poslat výsledek zpět pomocí setResult zasláním v resultCode a úmysl
Několik poznámek:
resultCode je používán pro určení aktivity vlajka na jeho zdroj aktivity, co to je stav (např. OK, Zrušit, atd.).
kód požadavku používá zdrojová aktivita ke zjištění, která Cílová aktivita vrací hovor.
mohli jsme vidět, že cílová aktivita nemá viditelnost kódu požadavku.
Nelegální startActivityForResult Fragment Tok
Fragment, máme také startActivityForResult funkce pro volání, a také onActivityResult funkce přepsat.
to vyvolává několik otázek … např. jak to funguje? Je to stejné jako činnost je startActivityForResult a onActivityResult? Jak jsou příbuzní?
krátká odpověď je, že jsou podobné, ale jemně odlišné. Častá příčina zmatku a chyby. Takže je důležité pochopit podobnost a rozdíly.
je znázorněn tok fragmentu.
níže je uveden diagram, který jasně ukazuje, jak to všechno funguje společně. Rozdíly s aktivitou startActivityForResult a onactivityresult flow jsou zbarveny červeně.
Pojďme se více komplikované.
když voláme fragment ‚ s startActivityForResult (poznámka: not activity?.startActivityForResult), vytvoření cílové aktivity je stejné. Rozdíl je však v aktivitěvýsledek.
startActivityForResult()
musí to zvládnout z fragment
‚s onActivityForResult()
getActivity().startActivityForResult()
musí to zvládnout z activity
s onActivityForResult()
Pokud jste na fragment
a chcete zpracovat výsledek na fragment
onActivityForResult()
, v opačném případě, pokud chcete zvládnout z activity
fragmentu, použití getActivity.startActivityForResult()
Když Android SDK vrátí onActivityResult, žádost kód byl změněn. 0xP0000 je připojen k původnímu requestCode.
hodnota P začíná od 1 a zvyšuje se pro každý výsledek onActivityResult je volána ze stejného cílového fragmentu. (Pokud je volán jiný cílový Fragment, hodnota P je resetována).
např. pokud je původní requestCode 0xFF (tj. 255), requestCode návrat poprvé bude 0x100FF. Podruhé return requestCode bude 0x200FF.
po návratu do onactivityresult zdrojové aktivity se očekává, že by měl volat super.onActivityResult, které sídlí v FragmentActivity (rodič AppCompatActivity)
onActivityResult v FragmentActivity bude pak extract P-hodnotu (pomocí requestCode >> 16). P je index pole, kde je uložen zdrojový fragment. (např. pokud requestCode je 0x200FF, pak 0x200FF >> 16 = 2)
Pomocí P-hodnoty, to má nyní přístup ke zdroji fragment, který se používá v kroku 9 níže.
nyní odstraní hodnotu P z requestCode (pomocí requestCode & 0xffff), aby se vrátil k původnímu kódu požadavku (např. pokud je requestCode 0x200FF, pak 0x200FF & 0xffff = 0xFF)
protože nyní získá původní kód požadavku, který zdrojový fragment vytvořil, mohl by volat onActivityResult zdrojového fragmentu s původním kódem požadavku.
některé základní body, které chtějí vědět.
A. chování Aktivita je startActivityForResult je odlišný od Fragmentu startActivityForResult
Ve Fragmentu, když říkáme activity?.startActivityForResult(...)
, Pak Fragment onActivityResult
nebude volána automaticky.
B. pokud přepíšeme výsledek aktivity onActivityResult, ujistěte se, že máme super.onActivityResult in place
pokud přepíšeme zdrojovou aktivitu onActivityResult
, ale zapomeneme mít super.onActivityResult
pak Fragment onActivityResult
nebude volán.
C. requestCode vidět v činnosti je onActivityResult se liší od jednoho fragmentu za předpokladu,
Vzhledem k důvodu, Android SDK připojeny P
requestCode
, v činnosti onActivityResult
, jsme se nikdy dostat stejné requestCode
. To občas způsobuje zmatek pro vývojáře při ladění kódu tam.
D. když je aktivita obnovena ze stavu (tj. onStateInstance != null), měl by se vyhnout opětovnému vytvoření jeho fragmentu.
při volání onActivityResult
se pokusil získat původní fragment. To se také provádí pro činnost, která je obnovena ze zabitého stavu (např. emulované pomocí Don ‚ t Keep Activity).
Takže pokud developer znovu Fragment pokaždé, když onCreate se nazývá (bez ohledu na to jestli je obnoven stav, nebo ne), pak původní Fragment, který byl obnoven, bude zničena, a onActivityResult
volajícího, fragment bude záhadně neměl být nazýván.
To je úskalí i pro mnohé zkušené vývojáře a app propuštěn v terénu, protože je velmi těžké zjištěna chyba (protože to se neděje pokaždé, když, a vyžadují složitější flow trigger).
Díky za přečtení …