¿Cómo funciona el nuevo FragmentTransaction commitNow () trabajando internamente?

El nuevo método commitNow () añadido en Android N y la versión 24 de la biblioteca de soporte tiene una documentación limitada y un poco confusa.

Confirma esta transacción de forma síncrona. Cualquier fragmento añadido se inicializará y se llevará completamente al estado de ciclo de vida de su anfitrión y cualquier fragmento eliminado será destruido en consecuencia antes de que esta llamada vuelva. Cometer una transacción de esta manera permite agregar fragmentos como componentes dedicados y encapsulados que supervisan el estado del ciclo de vida de su anfitrión, a la vez que proporcionan garantías de ordenamiento más firmes cuando los fragmentos están completamente inicializados y listos. Los fragmentos que administran vistas tendrán las vistas creadas y adjuntas.

Llamar commitNow es preferible a llamar a commit () seguido de FragmentManager.executePendingTransactions () ya que este último tendrá el efecto secundario de intentar confirmar todas las transacciones actualmente pendientes, ya sea que se trate del comportamiento deseado o no.

Las transacciones comprometidas de esta manera no se pueden agregar a la pila trasera del FragmentManager, ya que al hacerlo rompería otras garantías de pedidos esperadas para otras transacciones asincrónicamente comprometidas. Este método lanzará IllegalStateException si la transacción previamente solicitada se agregara a la pila de fondo con addToBackStack (String) .

Una transacción sólo se puede confirmar con este método antes de que contenga la actividad que guarde su estado. Si se intenta realizar el commit después de ese punto, se lanzará una excepción. Esto se debe a que el estado después del commit se puede perder si la actividad necesita ser restaurada de su estado. Consulte commitAllowingStateLoss () para situaciones en las que puede estar bien perder el commit.

He destacado en negrita la parte que creo que es confuso.

Por lo tanto, mis principales preocupaciones / preguntas son:

1 – ¿NO PUEDEN ser agregados? Dice que voy a obtener una IllegalStateException, por lo que será o no será añadido?

2 – Acepto el hecho de que no puedo usar esto si queremos agregar un fragmento en el backstack. Lo que no dice es que se obtiene esta excepción:

java.lang.IllegalStateException: This transaction is already being added to the back stack 

!!!! ????

Así que no puedo llamar a addToBackStack(String) yo mismo porque es internamente llamarlo para mí? Lo siento pero … ¿qué? ¿por qué? ¿Qué pasa si no quiero que se agregue en el backstack? ¿Y si trato de usar ese fragmento de la pila posterior más tarde, pero porque no se puede agregar, más tarde no está allí?

Parece que esto es algo esperado si estaba usando commitAllowingStateLoss() , pero veo que commitNowAllowingStateLoss() también existe, así que … ¿qué tipo de lógica sigue?

TL, DR

¿Cómo está commitNow () trabajando internamente con respecto a la backstack?

Es una buena cosa que el código fuente de Android es Open Source cuando nos enfrentamos a alguna pregunta como esta!

Responder

Así que echemos un vistazo a la fuente BackStackRecord aquí

 @Override public void commitNow() { disallowAddToBackStack(); mManager.execSingleAction(this, false); } @Override public FragmentTransaction disallowAddToBackStack() { if (mAddToBackStack) { throw new IllegalStateException( "This transaction is already being added to the back stack"); } mAllowAddToBackStack = false; return this; } 

Y mAddToBackStack se establecerá en true si llama a addToBackStack en la transacción.

Así que para responder a su pregunta, no addToBackStack no se llama internamente cuando se llama commitNow() , es el mensaje de excepción ambigous. Creo que debería decir You're not allowed to add to backstack when using commitNow() lugar del mensaje actual.

Prima:

Si profundizamos en el código fuente de FragmentManager aquí , commitNow() realidad está haciendo casi lo mismo que executePendingTransactions() como se escribió anteriormente, pero en lugar de ejecutar todas las transacciones previamente comprometidas, commitNow () sólo confirmará esa transacción.

Creo que esa es la razón principal por la que commitNow () no está permitiendo la adición a la backstack ya que no puede garantizar que no hay ninguna otra transacción pendiente. Si commitNow () puede agregar a la backstack, existe la posibilidad de que podamos romper nuestra secuencia backstack que conducirá a algo inesperado.

  • La biblioteca de la barra de acciones de AppCompat no muestra fragmentos añadidos
  • Android - Hacer traducciones y objectAnimator en el mismo archivo XML
  • Salir de la animación no funciona; FragmentTransaction animación personalizada no funciona para ocultar
  • Cómo agregar / quitar Fragmento en el botón haga clic?
  • Android: ¿Cuándo es apropiado utilizar FragmentTransaction.remove?
  • El artículo de DrawerLayout hace clic - ¿Cuándo es el momento adecuado para reemplazar el fragmento?
  • Cómo borrar backStack de soporte FragmentManager?
  • Ciclo de vida del fragmento - ¿Qué método se llama mostrar / ocultar?
  • Fragmento de Android La transacción con animación provoca que el flash blanco
  • Android: Fragmento de diálogo y problemas de Backstack
  • FragmentManager.getFragmens (). Size () no disminuyen después de FragmentTransaction.remove (Fragment)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.