Comprender el comportamiento de startActivityForResult para Fragmento y Actividad

Se permite una comunicación de 2 vías entre la actividad de origen y la actividad de destino de toda la actividad de inicio para resultados y onActivityResult. Su flujo es como se muestra en el diagrama a continuación.

Del flujo a continuación, podemos comprender fácilmente el flujo de Resultados de Onactivity de la Actividad de Origen a la Actividad de Destino

La llamada a la actividad de origen, inicia Activity Forresult enviando la intent junto con el código de solicitud al SDK de Android.

El SDK de Android abre la actividad según se indica en la Intent.
Una vez que la actividad de destino ha terminado con su trabajo, vuelve a su actividad de llamada.

Podría enviar el resultado de vuelta usando setResult enviando el código de resultado y la intent

Varias notas aquí:

El código de resultado es utilizado por la actividad de destino para marcar a su actividad de origen cuál es el estado (por ejemplo, ACEPTAR, Cancelar, etc.).

El código de solicitud es utilizado por la actividad de origen para saber qué actividad de destino devuelve la llamada.

Pudimos ver que la actividad de destino no tiene visibilidad del código de solicitud.

Indocumentados startActivityForResult Fragmento de Flujo

En el Fragmento, también tenemos startActivityForResult función a llamar, y también onActivityResult función de reemplazar.

Esto plantea varias preguntas…por ejemplo, ¿Cómo funciona? ¿Es lo mismo que el resultado inicial de la actividad y el resultado de la actividad? ¿Cómo se relacionan?
La respuesta corta es, son similares pero sutilmente diferentes. Una causa frecuente de confusión y error. Por lo tanto, es importante entender la similitud y las diferencias.

El flujo de fragmentos ilustrado.

A continuación se muestra el diagrama que ilustra claramente cómo funciona todo en conjunto. Las diferencias con el flujo startActivity Forresult de la actividad y onActivityResult se colorean en ROJO.

Vamos más detalles sobre ella.

Cuando llamamos a la actividad de inicio del fragmento Forresult (nota: ¿NO actividad?.startActivityForResult), la creación de destino de la actividad es la misma. Sin embargo, la diferencia radica en el resultado de la actividad.

startActivityForResult() debe manejarlo desde fragment onActivityForResult()

getActivity().startActivityForResult() debe manejarlo desde el onActivityForResult()

de activitySi está en un fragment y desea manejar el resultado en el fragment, use onActivityForResult(); de lo contrario, si desea manejarlo desde el activity del fragmento, usegetActivity.startActivityForResult()

Cuando el SDK de Android devuelve onActivityResult, el código de solicitud se ha alterado. Se adjunta un 0xP0000 al código de solicitud original.

El valor P comienza a partir de 1, y se incrementa para cada resultado de Onactivity se llama desde el mismo fragmento de destino. (Si se llama a otro fragmento de destino, el valor P se restablece).

por ejemplo, si el código de solicitud original es 0xFF (es decir, 255), el código de solicitud devuelto la primera vez será 0x100FF. El segundo código de solicitud de devolución será 0x200FF.

Al volver al resultado onActivityResult de la actividad de origen, se espera que llame a super.onActivityResult, que reside en FragmentActivity (el padre de AppCompatActivity)

El onActivityResult en FragmentActivity extraerá el valor P (utilizando el código de solicitud > > 16). La P es el índice de la matriz donde se almacena el fragmento de origen. (por ejemplo, si el código de solicitud es 0x200FF, entonces 0x200FF >> 16 = 2)

Usando el valor P, ahora tiene acceso al fragmento de origen, que se usa en el paso 9 a continuación.

Ahora, elimina el valor P del código de solicitud (usando requestCode & 0xffff), para volver al código de solicitud original (p. ej. si requestCode es 0x200FF, entonces 0x200FF & 0xffff = 0xFF)

Como ahora obtiene el código de solicitud original que el fragmento de origen creó, podría llamar al onActivityResult del fragmento de fuente con el código de solicitud original.

Algunos puntos básicos que quieren saber.

A. El comportamiento de la actividad startActivityForResult es diferente del de Fragment startActivityForResult

En Fragment, si llamamos a activity?.startActivityForResult(...), No se llamará automáticamente a Fragment onActivityResult.

B. Si anulamos el resultado onActivityResult de la actividad, asegúrese de que tenemos super.onActivityResult in place

Si sobrescribimos el onActivityResult de la actividad de origen, pero olvidamos tener super.onActivityResult, no se llamará al onActivityResult de Fragment.

C. El código de solicitud visto en el resultado onActivityResult de la actividad es diferente del fragmento proporcionado

Debido a la razón, Android SDK anexó P al requestCode, en el onActivityResult de la actividad, nunca obtendremos el requestCode idéntico allí. Esto a veces causa confusión al desarrollador al depurar el código allí.

D. Cuando se restaura una actividad desde el estado (es decir, ¡onStateInstance != null), debe evitar recrear su fragmento.

Cuando se llama a onActivityResult, intenta recuperar el fragmento original. Esto también se realiza para la actividad que se restaura desde un estado muerto (por ejemplo, emulado usando No mantener actividad).

Por lo tanto, si el desarrollador vuelve a crear el Fragmento cada vez que se llama a onCreate (independientemente de si es un estado restaurado o no), el Fragmento original que se restauró se destruirá, y onActivityResult de la persona que llama, el fragmento misteriosamente no se llamará.

Esto es un escollo incluso para muchos desarrolladores experimentados y aplicaciones lanzadas en el campo, ya que es muy difícil identificar un error (ya que no sucede siempre y requiere un flujo más complejo para activarlo).

Gracias por leer…