370 Stimmen

erhält die Ausnahme "IllegalStateException: Kann diese Aktion nach onSaveInstanceState nicht ausführen"

Ich habe eine Live-Android-Anwendung, und aus dem Markt habe ich folgende Stack-Trace erhalten und ich habe keine Ahnung, warum seine geschieht, wie seine nicht in Anwendungscode geschieht, aber seine immer verursacht durch einige oder das andere Ereignis aus der Anwendung (Annahme)

Ich verwende keine Fragmente, dennoch gibt es einen Verweis auf FragmentManager. Wenn jeder Körper kann etwas Licht auf einige versteckte Fakten werfen, 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)

3voto

royorange Punkte 31

Eine andere Möglichkeit, das Problem zu lösen, ist die Verwendung der neuesten Version von lifecycle-ktx mit kotlin.

lifecycleScope.launchWhenResumed {
    // your code with fragment or dialogfragment
}

Die Schließung wird nach der Wiederaufnahme des Zustands ausgeführt, so dass selbst diese Methode nach stop aufgerufen wird, wird sie sicher beendet, wenn die nächste Fortsetzung kommt.

Sie können auch Folgendes wählen

lifecycleScope.launchWhenCreated
// or
lifecycleScope.launchWhenStarted

um Ihrer Situation gerecht zu werden.

Der Code wird gelöscht, wenn die Zerstörung eingetreten ist.

Der Link zum Google-Dokument: https://developer.Android.com/kotlin/ktx#lifecycle

2voto

andep Punkte 7823

Lesen Sie http://chris-alexander.co.uk/on-engineering/dev/Android-fragments-within-fragments/

Artikel. fragment.isResumed() Überprüfung hilft mir in onDestroyView ohne Verwendung von onSaveInstanceState Methode.

2voto

Tobia Caneschi Punkte 59

Gleiches Problem bei mir und nach einem Tag Analyse aller Artikel, Blog und Stackoverflow habe ich eine einfache Lösung gefunden. Don't use savedInstanceState at all, das ist die Bedingung mit einer Zeile Code. Auf das Fragment Code:

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

2voto

Sharath kumar Punkte 3964

Dies geschieht immer dann, wenn Sie versuchen, ein Fragment zu laden, die Aktivität jedoch ihren Zustand in onPause() geändert hat. Dies geschieht beispielsweise, wenn Sie versuchen, Daten zu holen und in die Aktivität zu laden, der Benutzer jedoch bereits auf eine Schaltfläche geklickt hat und zur nächsten Aktivität übergegangen ist.

Sie können dies auf zwei Arten lösen

Sie können transaction.commitAllowingStateLoss() anstelle von transaction.commit() verwenden, um das Fragment zu laden, aber es kann passieren, dass die durchgeführte Commit-Operation verloren geht.

o

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

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

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

dann beim Laden des Fragments prüfen, ob Aktivität vorhanden ist und nur laden, wenn Aktivität im Vordergrund ist.

if(mIsResumed){
 //load the fragment
}

1voto

JianxinLi Punkte 23

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

Nach Angaben von doc :

 * 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 zu ersetzen:

fragmentTransaction.commit();
FragmentManager.executePendingTransactions()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X