¿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.
- Fragmento de Android: ¿se mueve de una vista a otra?
- ¿Qué hace exactamente FragmentManager y FragmentTransaction exactamente?
- Congelación de la interfaz de usuario cuando la transacción de fragmentos
- Cómo reemplazar un ViewPager con un fragmento
- Cambiar el orden z de Fragmentos durante la FragmentTransaction en curso
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?
- android.R.id.content como contenedor para Fragment
- Cómo agregar un fragmento a un diseño de un DialogFragment?
- Se hace clic en un diseño invisible detrás del fragmento:
- ViewPager dentro de Fragmento desaparece después de transaction.remove () (Mantener instancia?)
- ¿Cómo reemplazar el fragmento C con el fragmento A cuando se pulsa el botón Atrás?
- No se encontró ninguna vista para id - DialogFragment + Fragment
- Cómo mostrar el fragmento de entrada sobre el fragmento de salida mientras se anima.
- Fragmento Transacción cargar la vista vacía, pero el fragmento se muestra después de que el dispositivo giratorio
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.
- Android E / Parcel: Clase no encontrada al desmarcar (sólo en Samsung Tab3)
- Clase LocationClient no encontrada en los servicios de Google Play rev 22