IllegalStateException: Diese Aktion kann nach onSaveInstanceState mit ViewPager nicht ausgeführt werden
Bin ich erste user-Berichte aus meiner app auf dem Markt, die Bereitstellung der folgenden Ausnahme:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyUp(Activity.java:2044)
at android.view.KeyEvent.dispatch(KeyEvent.java:2529)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2028)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4028)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
Anscheinend hat es etwas damit zu tun, einen FragmentManager, die ich nicht verwenden. Der stacktrace zeigt keinen meiner eigenen Klassen, so habe ich keine Ahnung, wo diese Ausnahme tritt auf, und wie um es zu verhindern.
Für das Protokoll: ich habe einen tabhost, und in jeder Registerkarte gibt es ein ActivityGroup Wechsel zwischen Aktivitäten.
Kommentar zu dem Problem - Öffnen
Ich fand diese Frage diskutiert das gleiche Problem, aber keine Lösung da entweder.. stackoverflow.com/questions/7469082/...
Während Sie nicht mit
FragmentManager
, Honeycomb ist sicherlich. Ist dieses geschehen auf die Reale Honeycomb tablets? Oder könnte es sein, dass jemand mit einer gehackten Honeycomb auf einem Telefon oder so etwas, und es ist, gehackt edition, die Schwierigkeiten hat? Ich habe keine Ahnung. Dies ist die einzige information, die ich bekommen in den Markt der Entwickler-Konsole, der Benutzer-Nachricht enthält keine nützliche info entweder..
Ich bin mit der Flut, die zeigt mir 11 Sitzungen mit Android 3.0.1 und ich habe 11 Berichte von dieser Ausnahme. Könnte Zufall sein aber. Android 3.1 und 3.2 haben die 56 und 38 Sitzungen, beziehungsweise.
Der Markt Fehler-Bericht ist eine 'Plattform', manchmal, es hat die Android version des Gerätes.
InformationsquelleAutor der Frage nhaarman | 2011-09-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Überprüfen Sie bitte meine Antwort hier. Im Grunde musste ich nur noch :
Machen Sie nicht den Anruf an
super()
auf diesaveInstanceState
Methode. Dieses Durcheinander Dinge...Dies ist ein bekanntes bug in den support-Paket.
Wenn Sie die Instanz, und fügen Sie etwas zu Ihrem
outState
Bundle
können Sie die folgenden verwenden:Am Ende die richtige Lösung war (wie gesehen, in den Kommentaren) zu verwenden :
beim hinzufügen oder Durchführung der
FragmentTransaction
verursacht wurde dieException
.InformationsquelleAutor der Antwort Ovidiu Latcu
Gibt es viele ähnliche Probleme mit einer ähnlichen Fehlermeldung. Überprüfen Sie die zweite Zeile von diesem bestimmten stack-trace. Diese Ausnahme ist speziell im Zusammenhang mit dem Aufruf
FragmentManagerImpl.popBackStackImmediate
.Diese Methode aufrufen, wie
popBackStack
wird immer scheitern mitIllegalArgumentException
wenn der session state ist schon gespeichert. Überprüfen Sie die Quelle. Es gibt nichts, was Sie tun können, um dies zu stoppen Ausnahme ausgelöst wird.super.onSaveInstanceState
wird nicht helfen.commitAllowingStateLoss
wird nicht helfen.Hier, wie ich beobachtet das problem:
onSaveInstanceState
genannt wird.popBackStackImmediate
versucht wird.IllegalStateException
geworfen wird.Hier ist, was ich Tat, um es zu lösen:
Da es nicht möglich ist, zu vermeiden, die
IllegalStateException
im callback, fangen und ignorieren es.Dies ist genug, um die app abstürzt. Aber jetzt wird der Benutzer wiederherstellen Sie die app und sehen Sie, dass die Schaltfläche, die Sie dachten, Sie gedrückt nicht gedrückt wurde (Sie denken). Die form fragment wird noch zeigen!
Um dies zu beheben, wenn das Dialogfeld erstellt wird, stellen Sie einen Status angeben, der Prozess hat begonnen.
Und speichern Sie diesen Zustand in dem bundle.
Vergessen Sie nicht, laden es wieder in
onViewCreated
Dann, bei der Wiederaufnahme, Wiederherstellung der Fragmente, wenn unterbreiten, wurde bereits versucht. Dies verhindert, dass der Benutzer kommt zurück zu dem, was scheint wie eine un-vorgelegten form.
InformationsquelleAutor der Antwort Synesso
Überprüfen, ob die Aktivität
isFinishing()
bevor zeigt das fragment und achten Sie aufcommitAllowingStateLoss()
.Beispiel:
InformationsquelleAutor der Antwort Naskov
Hier ist eine andere Lösung für dieses problem.
Sich für eine private member-variable können Sie die zurückgegebenen Daten als eine Absicht, die dann bearbeitet werden, nachdem super.onResume();
Etwa so:
InformationsquelleAutor der Antwort Jed
Kurze Und funktionierende Lösung :
Folgen Sie Einfache Schritte,
Schritte
Schritt 1 : Überschreiben
onSaveInstanceState
Zustand im jeweiligen fragment. Und entfernen Sie super-Methode aus.Schritt 2 : Verwenden Sie
fragmentTransaction.commitAllowingStateLoss( );
statt
fragmentTransaction.commit( );
während fragment-Operationen.InformationsquelleAutor der Antwort Vinayak
VORSICHT, mit
transaction.commitAllowingStateLoss()
führen könnte eine schlechte Erfahrung für den Benutzer. Für mehr Informationen, warum diese Ausnahme wird geworfen, siehe dieser Beitrag.InformationsquelleAutor der Antwort Eric Brandwein
Fand ich eine schmutzige Lösung für diese Art von problem. Wenn Sie immer noch wollen, um Ihre
ActivityGroups
aus welchem Grund auch immer (ich hatte die Verjährung der Gründe), die Sie einfach umsetzenin Ihrem
Activity
und einigeback
code in es. auch wenn es keine solche Methode auch auf älteren Geräten, wird diese Methode aufgerufen wird, wird durch die neueren.InformationsquelleAutor der Antwort saberrider
Es ist Oktober 2017, und Google lässt Android-Support-Bibliothek, mit der neue Dinge zu nennen-Lifecycle-Komponente. Es bietet eine neue Idee für dieses 'nicht durchführen Kann diese Aktion nach onSaveInstanceState" problem.
Kurz:
Längere version mit erklären:
warum dieses problem kommen?
Es ist, weil Sie versuchen, zu verwenden
FragmentManager
von Ihrer Aktivität(die wird halten Sie Ihre fragment nehme ich an?) ein commit für eine Transaktion für Sie fragment. In der Regel würde dies so Aussehen, wie Sie versuchen zu tun, einige Transaktion für ein bis kommenden fragment, während die host-Aktivität bereits callsavedInstanceState
- Methode(user kann passieren, berühren Sie die home-Taste, so dass die Aktivität ruftonStop()
, in meinem Fall ist es der Grund)In der Regel dieses problem sollte nicht passieren-wir versuchen immer zu laden-fragment in die Aktivität, ganz am Anfang, wie die
onCreate()
Methode ist ein perfekter Ort für diese. Aber manchmal passieren, vor allem, wenn Sie sich nicht entscheiden kann, welches fragment Sie laden Sie zu Aktivität, oder Sie versuchen zu laden, fragment aus einemAsyncTask
block(oder alles dauert ein wenig Zeit). Die Zeit, bevor das fragment Transaktion wirklich passiert, aber nach der AktivitätonCreate()
Methode, der Benutzer kann nichts tun. Wenn Benutzer drücken Sie die home-Taste, die Auslöser der AktivitätonSavedInstanceState()
Methode, es wäre eincan not perform this action
Absturz.Wenn jemand will, um zu sehen, tiefer in dieses Problem, ich schlage vor, Sie nehmen einen Blick auf dieses blog post. Es schaut tief in die source-code-Ebene und erklären einem viel über es. Auch gibt es den Grund, dass Sie sollten nicht die
commitAllowingStateLoss()
Methode zur Umgehung dieses crash(Vertrauen Sie mir, es bietet nichts gutes für Ihren code)Wie man dieses Problem beheben?
Sollte ich
commitAllowingStateLoss()
Methode zum laden von fragment? NÖ, sollte Sie nicht;Soll ich überschreiben
onSaveInstanceState
Methode, ignorierensuper
Methode drin? NÖ, sollte Sie nicht;Sollte ich die magischen
isFinishing
im inneren Tätigkeit, um zu prüfen, ob die host-Aktivität ist im richtigen moment für fragment-Transaktion? Ja diese sieht aus wie die richtige Weise zu tun.Nehmen Sie einen Blick an, was Lebenszyklus Komponente tun können.
Im Grunde, Google macht einige Umsetzung innerhalb der
AppCompatActivity
Klasse(und einige andere Basisklasse, die Sie sollten in Ihrem Projekt verwenden), das macht es einfacher zu ermitteln der aktuellen Lebenszyklus-Status. Werfen Sie einen Blick zurück zu unserem problem: warum sollte dieses problem auftreten? Es ist, weil wir etwas tun, am falschen timing. So versuchen wir, es nicht zu tun, und das problem wird verschwunden sein.Code ich ein wenig für mein eigenes Projekt, hier ist, was ich Tue, mit
LifeCycle
. Ich code in Kotlin.Als ich oben zeige. Ich werde das überprüfen der Lebenszyklus-Status der host-Aktivität. Mit Lifecycle-Komponente innerhalb der support-Bibliothek, das könnte genauer sein. Der code
lifecyclecurrentState.isAtLeast(Lifecycle.State.RESUMED)
bedeutet, wenn der aktuelle Zustand mindestensonResume
, nicht später als? Das macht sicher, dass meine Methode nicht ausführen, während einige andere Leben Zustand(wieonStop
).Ist alles getan?
Natürlich nicht. Der code, den ich gezeigt habe, sagt eine neue Weise zu verhindern Anwendung abstürzt. Aber wenn Sie es tun, gehen Sie auf den Zustand der
onStop
ist, dass der code nicht Dinge tun, und so zeigen, dass nichts auf Ihrem Bildschirm. Wenn der Benutzer zurück zu der Anwendung, sehen Sie eine leere Leinwand, die leere host-Aktivität zeigt keine Fragmente an alle. Es ist schlechte Erfahrung(ja, ein bisschen besser als ein Absturz).So, hier ich wünschte, es könnte etwas schöner: die app wird nicht Abstürzen, wenn es um Leben Staat später als
onResume
der transaction-Methode Leben ist-Zustand bewusst; außerdem ist die Aktivität, die versuchen weiterhin zu fertigen, das fragment Transaktion Aktion, nachdem der Benutzer kommen zurück zu unserer app.Füge ich etwas mehr zu dieser Methode:
Ich behaupte, eine Liste innerhalb dieser
dispatcher
Klasse, diese lagern fragment keine chance haben, um die Transaktion abzuschließen action. Und wenn der Benutzer wieder aus der home-Bildschirm und gefunden es ist immer noch fragment warten, gestartet zu werden, es geht um dieresume()
Methode unter der@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
annotation. Jetzt denke ich, es sollte funktionieren wie ich es erwartet hatte.InformationsquelleAutor der Antwort Anthonyeef
Ich hatte ein ähnliches problem, das Szenario war so:
Den onCreate Methode der Aktivität war so:
Ausnahme wurde ausgelöst, weil die, wenn änderungen an der Konfiguration (Gerät gedreht), die Aktivität angelegt wird, wird das main-fragment wird abgerufen, aus der Geschichte der fragment manager und gleichzeitig das fragment bereits eine ALTEN Verweis auf die zerstört Tätigkeit
ändern der Umsetzung dieser das problem gelöst:
Sie benötigen, um Ihre Hörer jedes mal, wenn die activity erstellt wird, die situation vermeiden, wo die Fragmente sind Verweise auf alte zerstört Instanzen der Aktivität.
InformationsquelleAutor der Antwort Mina Samy
Nicht verwenden commitAllowingStateLoss(), es sollte nur verwendet werden, für Fälle, in denen es okay ist für den UI-Status zu ändern, der unerwartet auf den Benutzer.
https://developer.android.com/reference/android/app/FragmentTransaction.html#commitAllowingStateLoss()
Verwenden Sie stattdessen wenn (fragment.isResume()) check außerhalb der operation, die Sie trafen diese IllegalStateException "Kann nicht führen Sie diese Aktion nach onSaveInstanceState"
InformationsquelleAutor der Antwort Chandler
War ich immer zu dieser Ausnahme war, wenn ich drücken Sie die zurück-Taste, um abzubrechen intent chooser auf meiner Karte fragment-Aktivität.
Ich habe dieses Problem gelöst, indem Sie ersetzen den code, der onResume(wo ich war initialisieren der fragment) , onstart() und die app funktioniert gut.Hoffe, es hilft.
InformationsquelleAutor der Antwort DCS
Ich denke, mit
transaction.commitAllowingStateLoss();
ist nicht die beste Lösung.Diese Ausnahme wird geworfen, wenn die Aktivität der Konfiguration geändert und das fragment
onSavedInstanceState()
aufgerufen wird und danach die asynchrone callback-Methode versucht, einen commit-fragment.Einfache Lösung könnte sein, zu überprüfen, ob Aktivität ist die änderung der Konfiguration oder nicht
z.B. Scheck
isChangingConfigurations()
d.h.
if(!isChangingConfigurations()) {
//commit transaction.
}
Kasse diese link als auch
InformationsquelleAutor der Antwort Amol Desai
Vielleicht das glatteste und einfachste Lösung, die ich gefunden, in meinem Fall war, zu vermeiden knallen die problematische fragment aus dem Stapel in Reaktion auf die Tätigkeit Ergebnis. So verändert dieser Anruf in meinem
onActivityResult()
::
geholfen in meinem Fall.
InformationsquelleAutor der Antwort mojuba
Immer, wenn Sie versuchen zu laden, ein fragment, in Ihrer Aktivität stellen Sie sicher, dass die Aktivität im Lebenslauf und nicht auf pause Stand.Im pause-Modus, können Sie am Ende verlieren commit-operation, die getan wird.
Können Sie mit der Transaktion.commitAllowingStateLoss() anstelle von Transaktion.commit() zum laden von fragment
oder
Erstellen Sie eine Boolesche und überprüfen, ob die Aktivität ist nicht zu onpause
dann beim laden von fragment-check
InformationsquelleAutor der Antwort Anonymous
Wenn Sie tun, einige FragmentTransaction in onActivityResult, was Sie tun können, können Sie einige boolean-Wert in onActivityResult dann in der onResume Sie tun können, Ihre FragmentTransaction auf der Grundlage des booleschen Wertes. Bitte entnehmen Sie den folgenden code ein.
InformationsquelleAutor der Antwort anoopbryan2
Fügen Sie diese in Ihre Tätigkeit
InformationsquelleAutor der Antwort Balchander V R
Ab support library version 24.0.0 können Sie anrufen
FragmentTransaction.commitNow()
Methode, die verpflichtet dieser Transaktion synchron stattcommit()
gefolgt vonexecutePendingTransactions()
. Als Dokumentation sagt dieser Ansatz noch besser:InformationsquelleAutor der Antwort Volodymyr Khodonovych
Ich habe auch erlebt, dieses Problem und das problem jedes mal Auftritt, wenn der Kontext Ihrer
FragmentActivity
verändert wird (z.B. Bildschirm-Orientierung geändert wird, etc.). Also ist die beste Lösung für Sie ist zu aktualisieren Kontext von IhremFragmentActivity
.InformationsquelleAutor der Antwort Adam
Die Ausnahme ist, warf hier (In FragmentActivity):
In
FragmentManager.popBackStatckImmediate()
,FragmentManager.checkStateLoss()
heißt Erstens. Das ist die Ursache derIllegalStateException
. Die Umsetzung sehen Sie unten:Ich dieses problem lösen, indem man einfach ein flag zu markieren Aktivität über den aktuellen status. Hier ist meine Lösung:
}
InformationsquelleAutor der Antwort Frost Lau
Landete ich mit einem Basis-fragment und machen Sie alle Bruchstücke in meine app erweitern
Dann, wenn ich zu zeigen versuche ein fragment benutze ich
showAllowingStateLoss
stattshow
wie diese:
Kam ich zu dieser Lösung aus diesem PR: https://github.com/googlesamples/easypermissions/pull/170/files
InformationsquelleAutor der Antwort Ahmad El-Melegy
Andere mögliche Lösung, die ich bin mir nicht sicher, ob hilft in allen Fällen (Herkunft hier) :
InformationsquelleAutor der Antwort android developer
Ich weiß, es ist eine akzeptierte Antwort von @Ovidiu Latcu aber nach einiger Zeit, die Fehler bestehen immer noch.
Crashlytics immer noch senden Sie mir diese komische Fehlermeldung.
Jedoch Fehler jetzt auftreten nur auf version 7+ (Nougat)
Mein fix war zu verwenden commitAllowingStateLoss() anstatt von commit() auf das fragmentTransaction.
Diese post ist hilfreich für commitAllowingStateLoss() und hatte nie ein Problem fragment immer wieder.
Um es zusammenzufassen, die akzeptierte Antwort hier könnte die Arbeit an pre-Nougat android-Versionen.
Diese retten könnte jemand ein paar Stunden Suche.
glücklich Codierungen. <3 cheers
InformationsquelleAutor der Antwort ralphgabb