11
votes

Changement de fragment androïd et d'orientation provoquant: IllégalStateException: ne peut pas effectuer cette action après ersaveInstate

Je reçois cette erreur chaque fois que j'ai mon activité principale avec un fragment chargé et que l'utilisateur commence une nouvelle activité, bascule l'orientation de l'appareil et revient à l'activité principale.

07-27 11:56:20.399: E/AndroidRuntime(16021): FATAL EXCEPTION: main
07-27 11:56:20.399: E/AndroidRuntime(16021): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at com.rightcab.driver.core.HomeActivity.handleFragments(HomeActivity.java:341)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at com.rightcab.driver.core.HomeActivity.initialize(HomeActivity.java:128)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at com.rightcab.driver.core.HomeActivity.onConfigurationChanged(HomeActivity.java:153)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.app.ActivityThread.performConfigurationChanged(ActivityThread.java:3618)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.app.ActivityThread.handleActivityConfigurationChanged(ActivityThread.java:3771)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1328)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.os.Looper.loop(Looper.java:137)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at android.app.ActivityThread.main(ActivityThread.java:4745)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at java.lang.reflect.Method.invokeNative(Native Method)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at java.lang.reflect.Method.invoke(Method.java:511)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
07-27 11:56:20.399: E/AndroidRuntime(16021):    at dalvik.system.NativeStart.main(Native Method)


0 commentaires

4 Réponses :


1
votes

Utilisez-vous la dernière version de la bibliothèque Support-V4? Il a corrigé mon problème similaire.


0 commentaires

16
votes

Tout d'abord, comme je peux le voir, vous souhaitez gérer vous-même les changements de configuration. Afin de laisser fonctionner les choses correctement avec API Niveau 13+, vous devez ajouter une valeur de plus à configchange paramètre, comme décrit Ici .

Ensuite, lorsque l'utilisateur quitte votre activité principale, OnsaveInstancestate et OnaAUSe Les méthodes sont appelées. Lorsque l'utilisateur fait pivoter le périphérique et revenez à votre activité principale. OnconfigurationChaged La méthode est appelée avant tinrésume () . Donc, votre activité est toujours en pause et vous ne pouvez pas exécuter fragmenttransaction .

Plus de plus, si nous examinons le code source, nous pouvons voir le commentaire suivant pour OnResume < / Code> Méthode:

Dispatch onResume () à des fragments. Notez que pour mieux Inter-opération avec des versions plus anciennes de la plate-forme, au point de Cet appel Les fragments attachés à l'activité sont pas a repris. Cela signifie que dans certains cas, l'état précédent peut encore être enregistré, ne permettant pas de fragmenter les transactions qui modifient l'état. Pour interagir correctement avec des fragments dans leur état approprié, vous devriez au lieu de remplacer {@link #onresumefragments ()}.

Donc, le bon endroit pour manipuler des fragments de votre activité est de remplacer la méthode Onresumefragments , telle que nous pouvons lire dans le commentaire de cette méthode dans le code source:

Ceci est la version orientée fragment de {@link #ONRESume ()} Vous pouvez remplacer pour effectuer des opérations dans l'activité au même pointez là où ses fragments sont repris. Assurez-vous de toujours appeler à la super-classe. xxx


8 commentaires

Je ne peux pas utiliser les fragments ONRESUME car il n'est pas disponible dans mon activité. Peut-être parce que je suis construit contre le SDK 2.2? J'ai essayé d'ajouter des manuels () dans OneResume de l'activité, mais le résultat est toujours le même. Des idées ?


@Alin, si vous utilisez des fragments, votre activité devrait être dérivée de fragmentactivité et votre projet doit faire référence à la bibliothèque de compatibilité V4. OnresumeFragments est une méthode protégée de < code> fragmentactivité et vous pouvez le remplacer!


Vous avez raison, je dois avoir écrit le problème, j'ai essayé à nouveau et maintenant j'ai oneréfragments (). Le scénario que j'ai présenté auparavant semble fonctionner maintenant: OnResumeFragments J'appelle le guidon () et aucune erreur n'est tracé et la disposition du fragment changeait en fonction de l'orientation actuelle. Cependant, lorsque je suis dans une activité principale avec un fragment à l'écran et change d'orientation, mon manchefragmens ne s'appelle pas n'importe où donc je reste avec un endroit vide où le fragment devrait être. Alors ... comment devrais-je gérer le gicard dans l'encon -figurationChanged?


@Alin, comme je peux le voir, vous remplacez vos fragments en fonction de l'orientation actuelle. Alors, quelle est la raison pour gérer vous-même les changements d'orientation? @Alin, oui, lorsque vous faites pivoter le périphérique étant sur votre fragment principal, OnAUSE , ONRESUME , ONOSTRESUME ET ONRESUMEFRAGMENTS Les méthodes ne seront pas appelées parce que vous avez dit Android: "Je vais m'occuper de la configuration des changements moi-même!". Je vous suggère de vous débarrasser de configchange paramètre dans androidmanifest.xml et définissez une nouvelle mise en page dans Oncreate méthode.


En fait, je pense que je pensais que je l'ai compris: si je fais un drapeau à l'intérieur de l'onpause et que j'appuie que l'application est en pause, n'utilisez pas de manipulations () dans ONCONFigurationCommé. Maintenant, il semble fonctionner, fera des tests supplémentaires


À la fin de la solution avec ONRESUMEFRAGMAGES, associée à un drapeau de l'onpause fonctionnait très bien. Cependant, comme vous l'avez dit, il n'est pas nécessaire de prendre soin des configchanges. Donc, je laisse juste que l'activité soit recréée lorsque les valeurs importantes sont stockées dans une classe mondiale et je peux facilement recréer le statut de l'application. Merci


@Stenavin Pouvez-vous partager comment / où vous avez identifié les exemples de code source Android? (IE: Où ce code pourrait-il être pour moi d'examiner dans mon environnement Eclipse GNU / Linux?)


Cher Dieu, tu ne sais pas combien d'heures j'ai perdu d'essayer de comprendre pourquoi mon remplacement () ne fonctionnait pas. Heures juste pour changer l'onResume dans ONRESUMEFRAGMAGES. Merci!



6
votes

si comme STENAVIN suggère OnconfigurationChanger () est renvoyé avant de reprendre () à venir Retour à votre activité:

Ceci est le cycle de vie: xxx

mais la partie importante est la suivante:

si vous reprenez une activité ou que vous modifiez l'orientation d'une activité Votre fragments ira bien! Vous n'avez pas besoin de remplacer l'ancien avec une nouvelle copie et, en fait, vous ne devriez pas! Si vous supprimez simplement cette ligne, vous n'aurez pas de problème: xxx

cependant si vous le faites parce que vous avez besoin de votre Fragment pour charger une nouvelle ressource de mise en page ( mise en page / frag.xml => mise en page-terre / frag.xml ) alors vous allez faire quelque chose comme ceci: xxx


6 commentaires

@Glereame, comme je l'ai mentionné dans ma première réponse, des fragments ne sont pas encore repris lorsque la méthode onctume de l'activité est terminée. Et vous ne pouvez toujours pas effectuer de transactions de fragment. Jetez un oeil à ce fichier \ extras \ android \ compatibilité \ v4 \ src \ java \ android \ supppo rt \ v4 \ app \ fragmentaireac ttivité.java . Vous pouvez effectuer des transactions de fragments dans ONPOSTRESUME ou ONRESUMEFRAGMENTMENT , appelant Super Mise en œuvre avant.


Je n'ai pas suggéré d'appeler fragmenttransaction.commit () dans tout autre état de cycle de vie que "repris" (AKA en cours d'exécution), je suggère de l'appeler uniquement lorsqu'un indicateur indiquant l'activité est dans l'état correct.


Je t'ai compris maintenant. Mais, quel est le sens de gérer l'orientation vous-même si vous souhaitez remplacer des fragments sur chaque changement d'orientation? Pourquoi ne laissez pas le système gérer les modifications d'orientation, supprimer le paramètre configchange et simplement définir la mise en page droite et instancier des fragments corrects dans Oncreate ?


Je suis d'accord - si vous souhaitez utiliser différentes ressources, vous devriez probablement faire de votre mieux pour ne pas remplacer le changement de configuration.


Oui, je me suis débarrassé de prendre soin des changements de configuration et cela fonctionne maintenant bien. Je devais juste m'assurer que les valeurs importantes sont dans une classe mondiale afin que je puisse facilement recréer le statut de l'application, merci graeme.


@Graeme concernant: Si vous reprenez une activité ou que vous modifiez l'orientation d'une activité, vos fragments seront bien! Et si le fragment a des mises en page différentes basées sur l'écran / l'orientation ... Dans ce cas, vous allez avoir à remplacer le fragment ...



1
votes

Si vous êtes bloqué à la version R7 de la bibliothèque de support (par exemple parce que vous utilisez Maven et désespoirement en attente d'une mise à jour ..)), vous pouvez utiliser Onpostresume pour éviter ce problème. . Si votre version est R11 ou supérieure, vous pouvez passer à ONRESUMEFRAGEMENTS .


0 commentaires