Verstehen Sie das Verhalten von startActivityForResult für Fragment und Aktivität
Dem gesamten startActivityForResult und onActivityResult ist eine 2-Wege-Kommunikation zwischen der Quell- und der Zielaktivität gestattet. Sein Fluss ist wie im Diagramm unten gezeigt.
Aus dem folgenden Fluss können wir den Fluss von onActivityResult von der Quell- zur Zielaktivität leicht verstehen
Der Quellenaktivitätsaufruf startActivityForResult durch Senden der Absicht zusammen mit dem Anforderungscode an Android SDK.
Android SDK öffnet dann die Aktivität entsprechend, wie in der Absicht angegeben.
Sobald die Zielaktivität ihren Job beendet hat, kehrt sie zu ihrer Aufruferaktivität zurück.
Das Ergebnis kann mit setResult zurückgesendet werden, indem der resultCode und die Absicht gesendet werden
Hier einige Hinweise:
Der resultCode wird von der Zielaktivität verwendet, um ihrer Quellaktivität den Status mitzuteilen (z. B. OK, Abbrechen usw.).
Der Anforderungscode wird von der Quellaktivität verwendet, um zu erfahren, welche Zielaktivität den Anruf zurückgibt.
Wir konnten sehen, dass die Zielaktivität keine Sichtbarkeit des Anforderungscodes hat.
Undokumentierter startActivityForResult-Fragmentfluss
In Fragment müssen wir auch die Funktion startActivityForResult aufrufen und die Funktion onActivityResult überschreiben.
Dies wirft mehrere Fragen auf … zB Wie funktioniert es? Ist es das gleiche wie die Aktivität startActivityForResult und onActivityResult? Wie sind sie verwandt?
Die kurze Antwort ist, sie sind ähnlich, aber subtil anders. Eine häufige Ursache für Verwirrung und Fehler. Daher ist es wichtig, die Ähnlichkeiten und Unterschiede zu verstehen.
Der dargestellte Fragmentfluss.
Unten ist das Diagramm, das deutlich zeigt, wie alles zusammenarbeitet. Die Unterschiede zum Fluss startActivityForResult und onActivityResult der Aktivität sind ROT dargestellt.
Lassen Sie uns näher darauf eingehen.
Wenn wir Fragments startActivityForResult aufrufen (Hinweis: KEINE Aktivität?.startActivityForResult), ist die Erstellung der Zielaktivität gleich. Der Unterschied ist jedoch das onActivityResult .
startActivityForResult()
muss es von der fragment
behandeln onActivityForResult()
getActivity().startActivityForResult()
muss es von activity
onActivityForResult()
Wenn Sie sich auf einem fragment
befinden und das Ergebnis auf fragment
verarbeiten möchten, verwenden Sie onActivityForResult()
, andernfalls, wenn Sie es von activity
des Fragments verarbeiten möchten, verwenden Sie getActivity.startActivityForResult()
Wenn Android SDK onActivityResult zurückgibt, wurde der Anforderungscode geändert. Ein 0xP0000 wird an den ursprünglichen requestCode angehängt.
Der P-Wert beginnt bei 1 und wird für jedes onActivityResult erhöht, das vom selben Zielfragment aufgerufen wird. (Wenn ein anderes Zielfragment aufgerufen wird, wird der P-Wert zurückgesetzt).
zB wenn der ursprüngliche Anforderungscode 0xFF (dh 255) ist, ist der Anforderungscode beim ersten Mal 0x100FF . Das zweite Mal Rückkehr requestCode wird 0x200FF sein.
Bei der Rückkehr zum onActivityResult der Quellaktivität wird erwartet, dass es super aufrufen sollte.onActivityResult, das sich in FragmentActivity (dem übergeordneten Element von AppCompatActivity) befindet
Das onActivityResult in FragmentActivity extrahiert dann den P-Wert (unter Verwendung von requestCode >> 16). Das P ist der Index des Arrays, in dem das Quellfragment gespeichert ist. (zB wenn requestCode 0x200FF ist, dann 0x200FF >> 16 = 2)
Mit dem P-Wert hat es nun Zugriff auf das Quellfragment, das in Schritt 9 unten verwendet wird.
Jetzt wird der P-Wert aus dem Anforderungscode entfernt (mit requestCode & 0xffff ), um zum ursprünglichen Anforderungscode zurückzukehren (z. wenn requestCode 0x200FF ist, dann 0x200FF & 0xffff = 0xFF)
Da jetzt der ursprüngliche Anforderungscode abgerufen wird, den das Quellfragment erstellt hat, kann das onActivityResult des Quellfragments mit dem ursprünglichen onActivityResult aufgerufen werden Anforderungscode.
Einige grundlegende Punkte, die wissen wollen.
A. Das Verhalten von Activity’s startActivityForResult unterscheidet sich von Fragment’s startActivityForResult
Wenn wir in Fragment activity?.startActivityForResult(...)
aufrufen, wird Fragment’s onActivityResult
nicht automatisch aufgerufen.
B. Wenn wir das onActivityResult der Aktivität überschreiben, stellen Sie sicher, dass wir super haben.onActivityResult anstelle von
Wenn wir die onActivityResult
der Quellaktivität überschreiben, aber vergessen, super.onActivityResult
zu haben, wird die onActivityResult
des Fragments nicht aufgerufen.
C. Der in onActivityResult der Aktivität onActivityResult unterscheidet sich von dem in
angegebenen Fragment Aus dem Grund, dass Android SDK P
an requestCode
angehängt hat. in der Aktivität onActivityResult
erhalten wir dort niemals das identische requestCode
. Dies führt manchmal zu Verwirrung beim Entwickler, wenn der Code dort debuggt wird.
D. Wenn eine Aktivität aus dem Status wiederhergestellt wird (dh onStateInstance != null), sollte es vermeiden, sein Fragment neu zu erstellen.
Wenn onActivityResult
aufgerufen wird, wurde versucht, das ursprüngliche Fragment abzurufen. Dies wird auch für die Aktivität durchgeführt, die aus einem getöteten Zustand wiederhergestellt wird (z. B. emuliert mit Aktivität nicht beibehalten).
Wenn der Entwickler das Fragment also jedes Mal neu erstellt, wenn onCreate aufgerufen wird (unabhängig davon, ob es sich um einen wiederhergestellten Zustand handelt oder nicht), wird das ursprüngliche Fragment, das wiederhergestellt wurde, zerstört, und onActivityResult
des Aufrufers wird das Fragment auf mysteriöse Weise nicht aufgerufen.
Dies ist eine Falle, auch für viele erfahrene Entwickler und App auf dem Gebiet veröffentlicht, da es sehr schwer zu einem identifizierten Fehler ist (da es nicht jedes Mal passiert, und erfordern einen komplexeren Fluss auszulösen).
Danke fürs Lesen…