Vérifier si l'état est enregistré avant de commettre un FragmentTransaction
Je vois parfois les suivantes stacktrace pour une livraison qui peuvent se produire lorsque l'utilisateur n'est pas à la recherche à l'activité (après enregistrement):
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
En regardant la source Android, c'est tout à fait logique:
private void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
}
}
Maintenant, je me demande si il n'y a aucune façon (en plus de stocker une variable de classe dans sur(Enregistrer/Restaurer)InstanceState) pour vérifier si un fragment est ou va être engagé dans un état indésirable, de cette façon, je peux stocker la transaction pour plus tard et faire la livraison en temps opportun.
- Êtes-vous essayer d'exécuter un
FragmentTransaction
deonNewIntent
méthode? - Éventuellement? Quelle différence cela fait-il?
- J'ai connu le même problème aujourd'hui et la raison en est que j'ai essayé d'ajouter un nouveau fragment de
onNewIntent
lorsque l'activité n'a pas repris encore.
Vous devez vous connecter pour publier un commentaire.
Puisque vous n'avez pas à joindre un exemple de code, tout ce que je peux deviner, c'est que vous êtes à l'aide de "mauvaise" méthode lors de la validation de la transaction.
donc, au lieu d'utiliser
FragmentTransaction.commit()
, vous devez utiliserFragmentTransaction.commitAllowingStateLoss().
Aussi, il y a des rapports et solutions sur ce problème (ou plutôt le changement de comportement de l'API) dans google blog.
À partir de l'appui de version de bibliothèque 26.0.0 Bêta 1 une nouvelle API est disponible dans
FragmentManager
etFragment
classes:De docs de
android.de soutien.v4.app.FragmentManager#isStateSaved()
:Cette API sera livré avec cadre de
android.app.FragmentManager
à partir de Android O.Il est malheureusement Android Fragment de ne pas fournir une API de vérifier si c'est bien pour valider une transaction.
Mais on peut ajouter un champ booléen dans cette activité nous aider à vérifier. Veuillez ref le code suivant.
Comme pour pourquoi choisir
onResumeFragment()
comme permettant de transaction indicateur, ref ce bon blog. Il explique célèbre IllegalStateException en détail.commitAllowingStateLoss()
n'est pas une façon correcte pour résoudre le problème.unluckily Android Fragment does not provide an API check if it is fine to commit transaction
Heureusement, ils le font savoir, qui est mentionné dans ceci la réponse.RuntimeExceptions (et à l'exception IllegalStateException est l'un d'entre eux), le plus souvent, votre code est incorrect sur la façon dont il a essayé de réaliser quelque chose. En essayant de gérer une telle exception (par exemple par l'attraper) est également faux. Votre code ne doit jamais comporter de la manière dont Android serait jeter l'exception de ce genre sur vous.
Si vous utilisez les Gestionnaires et les poster ou d'envoyer un message pour être traitées dans l'avenir, vous devez effacer la file d'attente avant de sortir de la reprise de l'état.
Aussi, vous ne pouvez pas démarrer AsyncTask de l'Activité et de valider une transaction dans onPostExecute parce que l'utilisateur pourrait aller retour à partir de votre Activité. Vous devez annuler et vérifiez si elle a été annulée.
Il y a beaucoup d'exemples comme ceux-là et tous sont causés par "temporaire" des fuites de mémoire, comme j'aime à les appeler.
Fondamentalement, votre code est mauvais et sans fournir, il est impossible de dire combien de.
ft.commitAllowingStateLose()
est votre meilleur pari dans cette situation. Toutefois, comme indiqué, il n'y a aucune garantie que votre état va persister.Vous devez appeler la méthode commit seulement dans ces méthodes OnCreate, OnResumeFragments,OnPostResume. De détails, vous pouvez lire ici Fragment de Transactions & l'Activité de l'État de la Perte
Voici un Kotlin exemple en tirant parti de la dernière isStateSaved() FragmentManager méthode: https://proandroiddev.com/kotlin-extensions-to-commit-fragments-safely-de06218a1f4
Voir j'ai aussi eu ce problème , je ne pouvais pas trouver une solution, n'importe où. J'ai essayé un travail autour de .Il fonctionne comme ceci. Prendre la fragment de transaction à partir d'un Gestionnaire de la place. Le gestionnaire doit être appelée avec un 2000 ms de RETARD .
Par exemple. sur l'appel de makeTransaction
Il a résolu le problème pour moi