Comment fonctionne le nouveau commitNow () FragmentTransaction en interne?

La nouvelle méthode commitNow () ajoutée à Android N et à la bibliothèque de support 24 a une documentation limitée et un peu compliquée.

Valide cette transaction de manière synchrone. Tous les fragments ajoutés seront initialisés et amenés complètement à l’état de cycle de vie de leur hôte et tous les fragments supprimés seront supprimés en conséquence avant que cet appel ne soit rétabli. La validation d’une transaction de cette manière permet d’append des fragments en tant que composants encapsulés dédiés qui surveillent l’état de cycle de vie de leur hôte tout en offrant des garanties de classement plus fermes lorsque ces fragments sont entièrement initialisés et prêts. Les fragments qui gèrent des vues auront ces vues créées et associées.

L’appel de commitNow est préférable à l’appel de commit () suivi de FragmentManager.executePendingTransactions () car ce dernier aura pour effet secondaire de tenter de valider toutes les transactions actuellement en attente, que ce soit le comportement souhaité ou non.

Les transactions validées de cette manière ne peuvent pas être ajoutées à la stack arrière de FragmentManager, car cela briserait d’autres garanties de commande attendues pour d’autres transactions validées de manière asynchrone. Cette méthode lancera une exception IllegalStateException si la transaction précédemment demandée à append à la stack arrière avec addToBackStack (Ssortingng) .

Une transaction ne peut être validée qu’avec cette méthode avant que son activité de sauvegarde ne sauvegarde son état. Si la validation est tentée après ce point, une exception sera lancée. Cela est dû au fait que l’état après la validation peut être perdu si l’activité doit être restaurée à partir de son état. Voir commitAllowingStateLoss () pour les situations où il peut être acceptable de perdre la validation.

J’ai souligné en gras la partie que je trouve déroutante.

Donc, mes principales préoccupations / questions sont:

1 – Ils ne peuvent pas être ajoutés? Il dit que je vais avoir une exception IllegalStateException, alors sera-t-il ou ne sera pas ajouté?

2 – J’accepte le fait que je ne peux pas utiliser cela si nous voulons append un fragment dans le backstack. Ce qu’il ne dit pas, c’est que vous obtenez cette exception:

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

!!!! ????

Donc, je ne peux pas appeler addToBackStack(Ssortingng) moi-même parce qu’il l’appelle en interne pour moi? Je suis désolé mais … quoi? Pourquoi? Et si je ne veux pas que cela soit ajouté à l’arrière-plan? Et si j’essaie plus tard d’utiliser ce fragment du backstack mais parce qu’il NE PEUT PAS être ajouté, plus tard, il n’est pas là?

Il semble que ce soit quelque chose de prévu si commitAllowingStateLoss() , mais je vois que commitNowAllowingStateLoss() existe aussi, alors … quel type de logique suit-il?

TL; DR

Comment commitNow () fonctionne-t-il en interne en ce qui concerne le backstack?

C’est une bonne chose que le code source d’Android soit Open Source lorsque nous avons rencontré des questions comme celle-ci!

Répondre

Alors regardons la source de BackStackRecord ici

 @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; } 

Et mAddToBackStack sera défini sur true si vous appelez addToBackStack dans votre transaction.

Donc, pour répondre à votre question, aucun addToBackStack n’est appelé en interne lorsque vous appelez commitNow() , c’est le message d’exception ambigu. Je pense que cela devrait dire que You're not allowed to add to backstack when using commitNow() place du message en cours.

Prime:

Si nous approfondissons le code source de FragmentManager ici , commitNow() fait presque la même chose que executePendingTransactions() comme écrit ci-dessus, mais exécutant toutes les transactions précédemment validées, commitNow () ne validera que cette transaction.

Je pense que c’est la raison principale pour laquelle commitNow () n’autorise pas l’ajout au backstack car il ne peut pas garantir qu’il n’y ait pas d’autre transaction en attente. Si commitNow () peut append à la backstack, il est possible que nous puissions briser notre séquence de backstack qui conduira à une chose inattendue.

De la documentation de commitNow :

Les transactions validées de cette manière ne peuvent pas être ajoutées à la stack arrière de FragmentManager, car cela briserait d’autres garanties de commande attendues pour d’autres transactions validées de manière asynchrone. Cette méthode lancera une exception IllegalStateException si la transaction précédemment demandée à append à la stack arrière avec addToBackStack (Ssortingng).