het gedrag van startActivityForResult voor Fragment en activiteit begrijpen
de volledige startactivity forresult en onactivity result is toegestaan een 2-weg communicatie tussen de bronactiviteit en de bestemming activiteit. De stroom is zoals weergegeven in het onderstaande diagram.
uit de onderstaande stroom kunnen we gemakkelijk de stroom van Onactiviteitsresult van Bronactiviteit naar Bestemmingsactiviteit begrijpen
de Source activity call, startActivityForResult door het verzenden van de intent samen met de aanvraagcode naar Android SDK.
Android SDK opent vervolgens de activiteit overeenkomstig zoals aangegeven in de intentie.
zodra de doelactiviteit is beëindigd met zijn taak, keert het terug naar zijn belleractiviteit.
het kan het resultaat terugsturen met behulp van setResult door de resultCode en intent
een aantal opmerkingen hier in te sturen:
de resultCode wordt gebruikt door de doelactiviteit om aan de bronactiviteit te markeren wat de status is (bijvoorbeeld OK, Cancel, enz.).
de aanvraagcode wordt gebruikt door de bronactiviteit om te weten welke bestemmingsactiviteit de oproep beantwoordt.
we konden zien dat de bestemmingsactiviteit geen zichtbaarheid van de aanvraagcode heeft.
ongedocumenteerde startActivityForResult Fragment Flow
In Fragment, hebben we ook startActivityForResult functie aan te roepen, en ook onActivityResult functie te overschrijven.
dit roept verschillende vragen op … bijvoorbeeld Hoe werkt het? Is het hetzelfde als de startactiviteit voor resultaat en onactiviteitresult? Hoe zijn ze gerelateerd?
het korte antwoord is, ze zijn vergelijkbaar, maar subtiel verschillend. Een frequente oorzaak van verwarring, en bug. Het is dus belangrijk om de gelijkenis en verschillen te begrijpen.
de fragmentstroom geïllustreerd.
Hieronder is het diagram het illustreert duidelijk hoe het allemaal samen werkt. De verschillen met activity ‘ s startActivityForResult en onactivity result flow zijn rood gekleurd.
laten we er meer over uitweiden.
wanneer we Fragment ‘ s startactivity forresult (opmerking: Geen activiteit?.startactivity forresult), het creëren van bestemming activiteit is hetzelfde. Het verschil is echter het enige activiteitsresultaat.
startActivityForResult()
moet het verwerken van de fragment
’s onActivityForResult()
getActivity().startActivityForResult()
moet het verwerken van de activity
’s onActivityForResult()
Als je op een fragment
en u wilt verwerken van het resultaat op de fragment
gebruik onActivityForResult()
, anders, als je wilt om het verwerken van de activity
van het fragment, gebruik getActivity.startActivityForResult()
Als Android SDK geeft onActivityResult, de aanvraag-code is gewijzigd. Een 0xP0000 wordt toegevoegd aan de oorspronkelijke aanvraagcode.
de P-waarde begint vanaf 1, en wordt verhoogd voor elk activiteitsresultaat wordt aangeroepen vanuit hetzelfde doelfragment. (Als een ander doelfragment wordt aangeroepen, wordt de P-waarde gereset).
bijvoorbeeld als de oorspronkelijke aanvraagcode 0xFF is (d.w.z. 255), zal de aanvraagcode de eerste keer 0x100FF zijn. De tweede keer return requestCode zal 0x200FF zijn.
bij terugkeer naar het onactiviteitsresultaat van de bronactiviteit, wordt verwacht dat het super moet aanroepen.onactiviteitsresultaat, dat zich in Fragmentactiviteit bevindt (de ouder van Appcompatactiviteit)
het onactiviteitsresultaat in Fragmentactiviteit zal dan de p-waarde extraheren (met behulp van de aanvraagcode >> 16). De P is de index van de array waar het bronfragment is opgeslagen. (bijvoorbeeld als de aanvraagcode 0x200FF is, dan 0x200FF >> 16 = 2)
met behulp van de P-waarde heeft het nu toegang tot het bronfragment, dat wordt gebruikt in stap 9 hieronder.
nu verwijdert het de p-waarde van de requestCode (met requestCode & 0xffff), om terug te gaan naar de oorspronkelijke requestcode (bijv. als de requestCode 0x200FF is, dan 0x200FF & 0xffff = 0xFF)
aangezien het nu de originele request code krijgt die het bronfragment heeft gemaakt, kan het de Activity result van het bronfragment aanroepen met de originele request code.
enkele fundamentele punten die u wilt weten.
A. het gedrag van de Startactivity forresult van activiteit verschilt van de Startactivity forresult
van Fragment In Fragment, als we activity?.startActivityForResult(...)
aanroepen, dan wordt de onActivityResult
van Fragment niet automatisch aangeroepen.
B. Als we het activiteitsresultaat van activiteit overschrijven, zorg er dan voor dat we super hebben.onActivityResult in plaats
als we de bronactiviteit onActivityResult
overschrijven, maar vergeten super.onActivityResult
te hebben, dan wordt de Fragment onActivityResult
niet aangeroepen.
C. De requestCode die wordt gezien in het activiteitsresultaat van de activiteit verschilt van het gegeven fragment
vanwege de reden dat Android SDK P
aan de requestCode
heeft toegevoegd, in de activiteit onActivityResult
krijgen we daar nooit de identieke requestCode
. Dit veroorzaakt soms verwarring bij de ontwikkelaar bij het debuggen van de code daar.
D. Wanneer een activiteit wordt hersteld vanuit de staat (d.w.z. in het geval van een staat != null), moet het voorkomen dat opnieuw zijn fragment.
wanneer onActivityResult
wordt aangeroepen, probeerde het het originele fragment op te halen. Dit wordt ook uitgevoerd voor de activiteit die wordt hersteld van een gedode staat (bijvoorbeeld geëmuleerd met gebruik van Don ‘ t Keep Activity).
dus als de ontwikkelaar het Fragment opnieuw maakt elke keer dat onCreate wordt aangeroepen (ongeacht of het een herstelde status is of niet), dan zal het oorspronkelijke Fragment dat werd hersteld worden vernietigd, en onActivityResult
van de aanroeper zal het fragment op mysterieuze wijze niet worden aangeroepen.
dit is een valkuil, zelfs voor veel ervaren ontwikkelaars en apps die in het veld zijn uitgebracht, omdat het erg moeilijk is om een geïdentificeerde bug te herkennen (omdat het niet elke keer gebeurt en een complexere flow vereist om te activeren).
Bedankt voor het lezen …