Ausnahmebedingung “IllegalStateException: Diese Aktion kann nach onSaveInstanceState nicht ausgeführt werden”

Ich habe eine Live-Android-Anwendung, und vom Markt habe ich folgende Stack-Trace erhalten und ich habe keine Ahnung, warum es geschieht, da es nicht im Anwendungscode passiert, sondern seine durch das eine oder andere Ereignis aus der Anwendung verursacht (Annahme)

Ich verwende keine Fragmente, trotzdem gibt es eine Referenz von FragmentManager. Wenn ein Körper etwas Licht auf versteckte Fakten casting kann, um diese Art von Problem zu vermeiden:

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.onKeyDown(Activity.java:1962) at android.view.KeyEvent.dispatch(KeyEvent.java:2482) at android.app.Activity.dispatchKeyEvent(Activity.java:2274) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1668) 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.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:1720) at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1258) at android.app.Activity.dispatchKeyEvent(Activity.java:2269) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1668) at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2851) at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2824) at android.view.ViewRoot.handleMessage(ViewRoot.java:2011) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:132) at android.app.ActivityThread.main(ActivityThread.java:4025) 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:841) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) at dalvik.system.NativeStart.main(Native Method) 

Dies ist der dümmste Fehler, den ich bisher erlebt habe. Ich hatte eine Fragment Anwendung, die perfekt für API <11 und Force Closing für API> 11 funktioniert.

Ich konnte wirklich nicht herausfinden, was sie im Activity Lifecycle im Aufruf von saveInstance , aber ich habe hier wie ich das getriggers:

 @Override protected void onSaveInstanceState(Bundle outState) { //No call for super(). Bug on API Level > 11. } 

Ich mache einfach keinen Anruf bei .super() und alles funktioniert .super() . Ich hoffe, das spart dir Zeit.

BEARBEITEN: Nach etwas mehr Forschung ist dies ein bekannter Fehler im Support-Paket.

Wenn Sie die Instanz speichern und etwas zu Ihrem outState Bundle hinzufügen outState , können Sie Folgendes verwenden:

 @Override protected void onSaveInstanceState(Bundle outState) { outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE"); super.onSaveInstanceState(outState); } 

EDIT2: Dies kann auch auftreten, wenn Sie versuchen, eine Transaktion auszuführen, nachdem Ihre Activity im Hintergrund ausgeführt wurde. Um dies zu vermeiden, sollten Sie commitAllowingStateLoss()

EDIT3: Die obigen Lösungen behebt Probleme in den frühen support.v4 Bibliotheken von dem, woran ich mich erinnern kann. Aber wenn Sie immer noch Probleme damit haben, müssen Sie auch @AlexLockwoods Blog lesen: Fragment Transactions & Activity State Loss

Zusammenfassung aus dem Blogpost (aber ich empfehle Ihnen dringend, es zu lesen):

  • NIEMALS commit() Transaktionen nach onPause() auf Pre-Honeycomb und onStop() auf Post-Honeycomb
  • Seien Sie vorsichtig, wenn Sie Transaktionen in Activity Lifecycle-Methoden festschreiben. Verwenden Sie onCreate() , onResumeFragments() und onPostResume()
  • Vermeiden Sie Transaktionen innerhalb von asynchronen Callback-Methoden
  • Verwenden Sie commitAllowingStateLoss() nur als letzten Ausweg

Wenn Sie im Android-Quellcode nachsehen, wodurch dieses Problem verursacht wird, hat das Flag mStateSaved in der FragmentManagerImpl class (die in Activity verfügbare Instanz) den Wert true. Es wird auf True gesetzt, wenn der Backstack beim Aufruf von Activity#onSaveInstanceState gespeichert wird (saveAllState). Danach setzen die Aufrufe von ActivityThread dieses Flag nicht mit den verfügbaren Reset-Methoden von FragmentManagerImpl#noteStateNotSaved() und dispatch() .

So wie ich es sehe, gibt es einige Fixes, abhängig davon, was Ihre App macht und verwendet:

Gute Wege

Vor allem anderen: Ich würde für Alex Lockwood Artikel werben. Dann von dem, was ich bisher gemacht habe:

  1. Für Fragmente und Aktivitäten, die keine Statusinformationen enthalten müssen, rufen Sie commitAllowStateLoss auf . Aus der Dokumentation entnommen:

    Ermöglicht die Ausführung des Commits, nachdem der Status einer Aktivität gespeichert wurde. Dies ist gefährlich, da die Festschreibung verloren gehen kann, wenn die Aktivität später aus ihrem Status wiederhergestellt werden muss. Daher sollte dies nur für Fälle verwendet werden, in denen der UI-Status für den Benutzer unerwartet geändert werden kann. Ich denke, das ist in Ordnung, wenn das Fragment schreibgeschützte Informationen enthält. Oder, selbst wenn sie bearbeitbare Informationen anzeigen, verwenden Sie die Callback-Methoden, um die bearbeiteten Informationen beizubehalten.

  2. Direkt nachdem die Transaktion festgeschrieben wurde (Sie haben gerade commit() aufgerufen), rufen Sie FragmentManager.executePendingTransactions() .

Nicht empfohlene Wege:

  1. Wie Ovidiu Latcu oben erwähnt, rufen super.onSaveInstanceState() nicht super.onSaveInstanceState() . Aber das bedeutet, dass Sie den gesamten Zustand Ihrer Aktivität zusammen mit Fragmenten verlieren werden.

  2. onBackPressed und dort nur call finish() aufrufen. Dies sollte in Ordnung sein, wenn Ihre Anwendung keine Fragment-API verwendet. Wie in super.onBackPressed gibt es einen Aufruf von FragmentManager#popBackStackImmediate() .

  3. Wenn Sie beide Fragments-APIs verwenden und der Status Ihrer Aktivität wichtig / wichtig ist, können Sie versuchen, die Reflection-API FragmentManagerImpl#noteStateNotSaved() . Aber das ist ein Hack, oder man könnte sagen, es ist ein Workaround. Ich mag es nicht, aber in meinem Fall ist es durchaus akzeptabel, da ich einen Code aus einer Legacy-App habe, der veralteten Code verwendet ( TabActivity und implizit LocalActivityManager ).

Unten ist der Code, der die Reflektion verwendet:

 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); invokeFragmentManagerNoteStateNotSaved(); } @SuppressWarnings({ "rawtypes", "unchecked" }) private void invokeFragmentManagerNoteStateNotSaved() { /** * For post-Honeycomb devices */ if (Build.VERSION.SDK_INT < 11) { return; } try { Class cls = getClass(); do { cls = cls.getSuperclass(); } while (!"Activity".equals(cls.getSimpleName())); Field fragmentMgrField = cls.getDeclaredField("mFragments"); fragmentMgrField.setAccessible(true); Object fragmentMgr = fragmentMgrField.get(this); cls = fragmentMgr.getClass(); Method noteStateNotSavedMethod = cls.getDeclaredMethod("noteStateNotSaved", new Class[] {}); noteStateNotSavedMethod.invoke(fragmentMgr, new Object[] {}); Log.d("DLOutState", "Successful call for noteStateNotSaved!!!"); } catch (Exception ex) { Log.e("DLOutState", "Exception on worka FM.noteStateNotSaved", ex); } } 

Prost!

Eine solche Ausnahme tritt auf, wenn Sie versuchen, einen Fragmentübergang durchzuführen, nachdem der onSaveInstanceState() Ihrer Fragmentaktivität aufgerufen wurde.

Ein Grund dafür kann sein, dass Sie eine AsyncTask (oder einen Thread ) verlassen, wenn eine Aktivität gestoppt wird.

Alle Übergänge nach dem onSaveInstanceState() können möglicherweise verloren gehen, wenn das System die Aktivität für Ressourcen zurückgewinnt und sie später neu erstellt.

Rufen Sie einfach super.onPostResume () auf, bevor Sie Ihr Fragment anzeigen, oder verschieben Sie Ihren Code in der onPostResume () -Methode nach dem Aufruf von super.onPostResume (). Dies triggers das Problem!

Dies kann auch passieren, wenn Sie nach einem gesperrten / ausgeblendeten Bildschirm den Befehl disney dismiss() auf einem Dialogfragment aufrufen und der Instanzstatus des Activity + -Dialogs gespeichert wurde. Um diesen Aufruf zu umgehen:

 dismissAllowingStateLoss() 

Wörtlich jedes Mal, wenn ich einen Dialog ablehne, kümmert es mich sowieso nicht mehr um seinen Zustand, also ist das in Ordnung – du verlierst eigentlich keinen Zustand.

Kurz und funktionierend Lösung:

Folge einfachen Schritten:

Schritt 1 : Überschreiben Sie onSaveInstanceState im entsprechenden Fragment. Und entfernen Sie super Methode daraus.

 @Override public void onSaveInstanceState(Bundle outState) { }; 

Schritt 2 : Verwenden Sie CommitAllowingStateLoss (); statt commit (); während Fragmentoperationen.

 fragmentTransaction.commitAllowingStateLoss(); 

das funktionierte für mich … fand es selbst heraus … hoffe es hilft dir!

1) habe keinen globalen “statischen” FragmentManager / FragmentTransaction.

2) onCreate, IMMER initialisiere den FragmentManager erneut!

Beispiel unten: –

 public abstract class FragmentController extends AnotherActivity{ protected FragmentManager fragmentManager; protected FragmentTransaction fragmentTransaction; protected Bundle mSavedInstanceState; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSavedInstanceState = savedInstanceState; setDefaultFragments(); } protected void setDefaultFragments() { fragmentManager = getSupportFragmentManager(); //check if on orientation change.. do not re-add fragments! if(mSavedInstanceState == null) { //instantiate the fragment manager fragmentTransaction = fragmentManager.beginTransaction(); //the navigation fragments NavigationFragment navFrag = new NavigationFragment(); ToolbarFragment toolFrag = new ToolbarFragment(); fragmentTransaction.add(R.id.NavLayout, navFrag, "NavFrag"); fragmentTransaction.add(R.id.ToolbarLayout, toolFrag, "ToolFrag"); fragmentTransaction.commitAllowingStateLoss(); //add own fragment to the nav (abstract method) setOwnFragment(); } } 

Das habe ich immer bekommen, als ich versucht habe, das Fragment in der Methode onActivityForResult () zu zeigen.

  1. Meine Aktivität wurde pausiert und gestoppt, was bedeutet, dass onSaveInstanceState () bereits aufgerufen wurde (sowohl für Pre-Honeycomb- als auch für Post-Honeycomb-Geräte).
  2. Im Falle eines Ergebnisses habe ich eine Transaktion gemacht, um das Fragment anzuzeigen / auszublenden, was diese IllegalStateException verursacht.

Was ich gemacht habe, ist das nächste:

  1. Zusätzlicher Wert um zu bestimmen, ob die gewünschte Aktion gemacht wurde (zB Foto von Camere nehmen – isPhotoTaken) – es kann ein boolscher oder ein ganzzahliger Wert sein, abhängig davon wieviele Transaktionen benötigt werden.
  2. In overriden onResumeFragments () -Methode habe ich nach meinem Wert überprüft und nach der Durchführung von Fragment-Transaktionen, die ich brauchte. In diesem Fall wurde commit () nicht nach onSaveInstanceState ausgeführt, da in der Methode onResumeFragments () der Status zurückgegeben wurde.

Ich habe das Problem mit onconfiguration geändert. Der Trick besteht darin, dass Sie im Lebenszyklus der Android-Aktivität explizit eine Absicht (Kameraabsicht oder eine andere Absicht) aufrufen. Die Aktivität wird pausiert und in diesem Fall wird onSavedInstance aufgerufen. Wenn das Gerät an eine andere Position gedreht wird als die, während der die Aktivität aktiv war; Das Ausführen von Fragmentoperationen, wie z. B. Fragment-Commit, verursacht eine Ausnahme wegen eines ungültigen Status. Es gibt viele Beschwerden darüber. Es ist etwas über Android Lifecycle-Management-Aktivität und ordnungsgemäße Methodenaufrufe. Um das Problem zu lösen, habe ich Folgendes getan: 1-Überschreibe die OnSavedInstance-Methode deiner Aktivität und bestimme die aktuelle Bildschirmausrichtung (Hoch- oder Querformat) und setze deine Bildschirmausrichtung darauf, bevor deine Aktivität angehalten wird. Auf diese Weise sperren Sie die Bildschirmdrehung für Ihre Aktivität, falls sie durch eine andere gedreht wurde. 2 – Überschreiben Sie dann die Onesume-Methode der Aktivität, und stellen Sie Ihren Orientierungsmodus jetzt auf den Sensor ein, so dass nach dem Aufruf der OnSaved-Methode eine weitere On-Konfiguration aufgerufen wird, um mit der Rotation richtig umzugehen.

Sie können diesen Code kopieren und in Ihre Aktivität einfügen, um damit umzugehen:

 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Toast.makeText(this, "Activity OnResume(): Lock Screen Orientation ", Toast.LENGTH_LONG).show(); int orientation =this.getDisplayOrientation(); //Lock the screen orientation to the current display orientation : Landscape or Potrait this.setRequestedOrientation(orientation); } //A method found in stackOverflow, don't remember the author, to determine the right screen orientation independently of the phone or tablet device public int getDisplayOrientation() { Display getOrient = getWindowManager().getDefaultDisplay(); int orientation = getOrient.getOrientation(); // Sometimes you may get undefined orientation Value is 0 // simple logic solves the problem compare the screen // X,Y Co-ordinates and determine the Orientation in such cases if (orientation == Configuration.ORIENTATION_UNDEFINED) { Configuration config = getResources().getConfiguration(); orientation = config.orientation; if (orientation == Configuration.ORIENTATION_UNDEFINED) { // if height and widht of screen are equal then // it is square orientation if (getOrient.getWidth() == getOrient.getHeight()) { orientation = Configuration.ORIENTATION_SQUARE; } else { //if widht is less than height than it is portrait if (getOrient.getWidth() < getOrient.getHeight()) { orientation = Configuration.ORIENTATION_PORTRAIT; } else { // if it is not any of the above it will defineitly be landscape orientation = Configuration.ORIENTATION_LANDSCAPE; } } } } return orientation; // return value 1 is portrait and 2 is Landscape Mode } @Override public void onResume() { super.onResume(); Toast.makeText(this, "Activity OnResume(): Unlock Screen Orientation ", Toast.LENGTH_LONG).show(); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); } 

Ich denke, der Lifecycle-Status kann helfen, einen solchen Absturz zu verhindern, beginnend mit der Android-Support-Bibliothek lib v26.1.0. Sie können folgende Überprüfung durchführen:

 if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)){ // Do fragment's transaction commit } 

oder du kannst versuchen:

 Fragment.isStateSaved() 

Weitere Informationen finden Sie hier https://developer.android.com/reference/android/support/v4/app/Fragment.html#isStateSaved ()

Ich hatte das gleiche Problem, IllegalStateException zu bekommen, aber das Ersetzen aller meiner Aufrufe von commit () mit commitAllowingStateLoss () half nicht.

Der Schuldige war ein Aufruf von DialogFragment.show ().

Ich umgebe es mit

 try { dialog.show(transaction, "blah blah"); } catch(IllegalStateException e) { return; } 

und das hat es getan. OK, ich kann den Dialog nicht zeigen, aber in diesem Fall war das in Ordnung.

Es war der einzige Ort in meiner App, an dem ich zuerst FragmentManager.beginTransaction () aufgerufen habe, aber nie commit () aufgerufen habe, also habe ich es nicht gefunden, als ich nach “commit ()” gesucht habe.

Das Lustige ist, dass der Nutzer die App nie verlässt. Stattdessen wurde eine AdMob-Interstitial-Anzeige eingeblendet.

Meine Lösung für dieses Problem war

Im Fragment add Methoden:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... guideMapFragment = (SupportMapFragment)a.getSupportFragmentManager().findFragmentById(R.id.guideMap); guideMap = guideMapFragment.getMap(); ... } @Override public void onDestroyView() { SherlockFragmentActivity a = getSherlockActivity(); if (a != null && guideMapFragment != null) { try { Log.i(LOGTAG, "Removing map fragment"); a.getSupportFragmentManager().beginTransaction().remove(guideMapFragment).commit(); guideMapFragment = null; } catch(IllegalStateException e) { Log.i(LOGTAG, "IllegalStateException on exit"); } } super.onDestroyView(); } 

Mag schlecht sein, konnte aber nichts besseres finden.

Ich habe das gleiche Problem in meiner App. Ich habe dieses Problem getriggers, indem ich einfach die super.onBackPressed(); in der vorherigen class und Aufruf der commitAllowingStateLoss() für die aktuelle class mit diesem Fragment.

onSaveInstance wird aufgerufen, wenn ein Benutzer den Bildschirm so dreht, dass er Ressourcen laden kann, die mit der neuen Ausrichtung verknüpft sind.

Es ist möglich, dass dieser Benutzer den Bildschirm gedreht hat und anschließend die Zurück-Taste gedrückt hat (weil es auch möglich ist, dass dieser Benutzer während der Verwendung der App an seinem Telefon herumgefummelt hat)

Ich habe dieses Problem.Aber ich denke, dass dieses Problem nicht mit commit und commitAllowStateLoss zusammenhängen.

Die folgende Stack-Trace- und Exception-Nachricht bezieht sich auf commit ().

 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1341) at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1352) at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574) 

Aber diese Ausnahme wurde von onBackPressed () verursacht

 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(Unknown Source) at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(Unknown Source) at android.support.v4.app.FragmentActivity.onBackPressed(Unknown Source) 

Sie wurden alle von checkStateLoss () verursacht

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

mStateSaved ist nach onSaveInstanceState wahr.

Dieses Problem tritt selten auf. Ich habe dieses Problem nie kennengelernt. Ich kann das Problem nicht erneut auftreten.

Ich habe das Problem 25517 gefunden

Es könnte unter den folgenden Umständen aufgetreten sein

  1. Die Zurück-Taste wird nach onSaveInstanceState aufgerufen, aber bevor die neue Aktivität gestartet wird.

  2. Verwenden Sie onStop () im Code

Ich bin mir nicht sicher, was die Wurzel des Problems ist. Also habe ich einen hässlichen Weg benutzt.

 @Override public void onBackPressed() { try{ super.onBackPressed(); }catch (IllegalStateException e){ // can output some information here finish(); } } 

Lesen Sie http://chris-alexander.de/on-engineering/dev/android-fragments-within-fragments/

Artikel. fragment.isResumed () hilft mir bei onDestroyView ohne die onSaveInstanceState Methode.

Das gleiche Problem von mir und nach einer langen Analyse aller Artikel, Blog und Stackoverflow habe ich eine einfache Lösung gefunden. Verwenden Sie savedInstanceState überhaupt nicht, dies ist die Bedingung mit einer Codezeile. Auf dem Fragmentcode:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(null); ..... 

Dies geschieht immer dann, wenn Sie versuchen, ein Fragment zu laden, aber die Aktivität hat ihren Status in onPause () geändert, beispielsweise wenn Sie versuchen, Daten abzurufen und in die Aktivität zu laden, aber zu dem Zeitpunkt, an dem der Benutzer auf eine Schaltfläche geklickt hat zur nächsten Aktivität gewechselt.

Sie können dies auf zwei Arten lösen

Sie können transaction.commitAllowingStateLoss () anstelle von transaction.commit () verwenden, um ein Fragment zu laden, aber Sie könnten dadurch einen Commit-Vorgang verlieren, der ausgeführt wird.

oder

Stellen Sie sicher, dass die Aktivität fortgesetzt wird und beim Laden eines Fragments nicht angehalten wird. Erstellen Sie einen booleschen Wert und überprüfen Sie, ob die Aktivität nicht in den Zustand onPause () wechselt.

 @Override public void onResume() { super.onResume(); mIsResumed = true; } @Override public void onPause() { mIsResumed = false; super.onPause(); } 

Überprüfen Sie dann beim Laden des Fragments, ob eine Aktivität vorhanden ist, und laden Sie sie nur, wenn die Aktivität Vordergrund ist.

 if(mIsResumed){ //load the fragment } 

Nun, nachdem ich alle oben genannten Lösungen ohne Erfolg versucht habe (weil ich grundsätzlich keine Transaktionen habe).

In meinem Fall habe ich AlertDialogs und ProgressDialog als Fragmente verwendet, die manchmal bei der Rotation bei der Frage nach dem FragmentManager auftauchen.

Ich habe einen Workaround gefunden, indem ich einige ähnliche Beiträge gemischt habe:

Es ist eine 3-Schritte-Lösung, alles auf Ihrer FragmentActivity (in diesem Fall heißt es GenericActivity):

 private static WeakReference activity = null; //To avoid bug for fragments: Step 1 of 3 @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); //To avoid bug for fragments: Step 2 of 3 activity = new WeakReference(this); } @Override public FragmentManager getSupportFragmentManager(){ //To avoid bug for fragments: Step 3 of 3 if (this == activity.get()) { return super.getSupportFragmentManager(); } return activity.get().getSupportFragmentManager(); } 

Wenn ich die Staraktivität in einem Fragment verwende, bekomme ich diese Ausnahme;

Wenn ich startactivityforresult verwende, ist die Ausnahme weg 🙂

Also die einfache Möglichkeit, es zu beheben, ist die StartActivityForResult API 🙂

Ich habe diese Ausnahme erhalten, als ich die Zurück-Taste gedrückt habe, um die Absichtsauswahl auf meiner Kartenfragmentaktivität abzubrechen. Ich triggerse das, indem ich den Code von onResume () (wo ich das Fragment initialisierte und die Transaktion festlegte) zu onStart () ersetzte und die App funktioniert jetzt gut. Ich hoffe es hilft.

Dies ist in Android 4.2 und auch in der Quelle der Support-Bibliothek behoben. [*]

Einzelheiten zur Ursache (und zu Work-Arounds) finden Sie im Google-Fehlerbericht: http://code.google.com/p/android/issues/detail?id=19917

Wenn Sie die Support-Bibliothek verwenden, sollten Sie sich nicht lange um diesen Fehler kümmern müssen [*]. Wenn Sie jedoch die API direkt verwenden (dh den FragmentManager der Support-Bibliothek nicht verwenden) und eine API unter Android 4.2 targetieren, müssen Sie eine der Umgehungslösungen ausprobieren.

[*] Zum Zeitpunkt der Erstellung dieses Artikels vertreibt der Android SDK-Manager noch eine alte Version, die diesen Fehler aufweist.

Bearbeiten Ich werde hier einige Erläuterungen hinzufügen, weil ich offensichtlich irgendwie verwirrt habe, wer auch immer diese Antwort abgelehnt hat.

Es gibt mehrere verschiedene (aber verwandte) Umstände, die dazu führen können, dass diese Ausnahme ausgetriggers wird . Meine obige Antwort bezieht sich auf die spezifische Instanz, die in der Frage diskutiert wird, dh auf einen Fehler in Android, der später behoben wurde. Wenn Sie diese Ausnahme aus einem anderen Grund erhalten, liegt das daran, dass Sie Fragmente hinzufügen / entfernen, wenn Sie nicht möchten (nachdem Fragmentstatus gespeichert wurden). Wenn Sie in einer solchen Situation sind, dann vielleicht ” Verschachtelte Fragmente – IllegalStateException” Kann diese Aktion nicht nach onSaveInstanceState ausführen ” ” kann für Sie von Nutzen sein.

Nach der Forschung ein wenig die Lösung für dieses Problem ist, Ihr Fragment in der Onesume zu tun.

Quelle: https://wenchaojames.wordpress.com/2013/01/12/illegalstateexception-from-onactivityresult/

Mein Anwendungsfall: Ich habe Listener in Fragment verwendet, um Aktivitäten zu melden, dass etwas passiert ist. Ich habe einen neuen Fragment-Commit für die Callback-Methode durchgeführt. Das funktioniert beim ersten Mal einwandfrei. Bei einer Orientierungsänderung wird die Aktivität jedoch mit dem gespeicherten Instanzstatus neu erstellt. In diesem Fall wird das Fragment nicht erneut erzeugt, impliziert, dass das Fragment den Listener hat, der eine alte zerstörte Aktivität ist. Jede Art und Weise, wie die callbackmethode bei einer Aktion ausgetriggers wird. Es geht um zerstörte Aktivitäten, die das Problem verursachen. Die Lösung besteht darin, den Listener im Fragment mit der aktuellen Live-Aktivität zurückzusetzen. Dies triggers das Problem.

Was ich fand, ist, dass, wenn eine andere App Dialogart ist und Berührungen an die Hintergrund-App gesendet werden können, fast jede Hintergrund-App mit diesem Fehler abstürzen wird. Ich denke, wir müssen jedes Mal überprüfen, ob eine Transaktion ausgeführt wird, wenn die Instanz gespeichert oder wiederhergestellt wurde.

In meinem Fall, mit der gleichen Fehlerausnahme, habe ich die “onBackPressed ()” in einem runnable (Sie können jede Ihrer Ansicht verwenden):

 myView.post(new Runnable() { @Override public void run() { onBackPressed() } }); 

Ich verstehe nicht warum, aber es funktioniert!

Möglicherweise rufen Sie fragmentManager.popBackStackImmediate (); wenn die Aktivität pausiert ist. Die Aktivität ist nicht beendet, sondern angehalten und nicht im Vordergrund. Sie müssen vor popBackStackImmediate () prüfen, ob die Aktivität pausiert ist oder nicht.

Danke @gunar, aber ich denke es gibt einen besseren Weg.

Laut Arzt:

  * If you are committing a single transaction that does not modify the * fragment back stack, strongly consider using * {@link FragmentTransaction#commitNow()} instead. This can help avoid * unwanted side effects when other code in your app has pending committed * transactions that expect different timing. * * @return Returns true if there were any pending transactions to be * executed. */ public abstract boolean executePendingTransactions(); 

Verwenden Sie also commitNow zum Ersetzen:

 fragmentTransaction.commit(); FragmentManager.executePendingTransactions() 

Ich habe etwas sehr interessantes bemerkt. Ich habe in meiner App die Option, die Galerie des Telefons zu öffnen und das Gerät fragt, welche App zu verwenden ist, da klicke ich auf den grauen Bereich weg von dem Dialog und sah dieses Problem. Ich habe bemerkt, wie meine Aktivität von onPause, onSaveInstanceState zurück zu onResume geht, es passiert nicht, onCreateView zu besuchen. Ich mache Transaktionen bei onResume. Also, was ich getan habe, ist das Setzen eines Flags, das onPause negiert wird, aber aufCreateView wahr ist. Wenn das Flag onResume wahr ist, dann mach onCommit, ansonsten commitAllowingStateLoss. Ich könnte weitermachen und so viel Zeit verschwenden, aber ich wollte den Lebenszyklus überprüfen. Ich habe ein Gerät, das ist SDKversion 23, und ich bekomme dieses Problem nicht, aber ich habe ein anderes, das 21 ist, und da sehe ich es.

Sie können FragmentVactivity.onStart vor popBackStackImmediate verwenden

so was:

 public void backStackFragment() { this.start(); getFragmentManager().popBackStackImmediate(); } public void start(){ FragmentActivity a = getActivity(); if(a instanceof DepositPlanPadActivity){ ((DepositPlanPadActivity)a).onStart(); } if(a instanceof SmallChangePlanPad){ ((SmallChangePlanPad)a).onStart(); } if(a instanceof UserCenterActivity){ ((UserCenterActivity)a).onStart(); } } 

http://jorryliu.blogspot.com/2014/09/illegalstateexception-can-not-perform.html