Ich habe den folgenden Code in meinem onActivityResult für ein Fragment von mir:
onActivityResult(int requestCode, int resultCode, Intent data){
//other code
ProgressFragment progFragment = new ProgressFragment();
progFragment.show(getActivity().getSupportFragmentManager(), PROG_DIALOG_TAG);
// other code
}
Ich erhalte jedoch den folgenden Fehler:
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
Weiß jemand, was los ist oder wie ich das beheben kann? Ich sollte beachten, dass ich das Android Support Package verwende.
android
android-fragments
android-dialogfragment
Kurtis Nusbaum
quelle
quelle
onResumeFragments()
dies in derActivity
Klasse nicht vorhanden ist . Wenn Sie ein Basic verwendenActivity
, sollten SieonPostResume()
stattdessen verwenden.EDIT: Kein Fehler, sondern eher ein Mangel im Fragment-Framework. Die bessere Antwort auf diese Frage ist die von @Arcao oben.
---- Originaler Beitrag ----
Eigentlich ist es ein bekannter Fehler mit dem Support-Paket (bearbeiten: eigentlich kein Fehler. Siehe @ alex-lockwoods Kommentar). Eine in den Kommentaren des Fehlerberichts veröffentlichte Problemumgehung besteht darin, die Quelle des DialogFragments wie folgt zu ändern:
Beachten Sie, dass dies ein riesiger Hack ist. So wie ich es tatsächlich gemacht habe, habe ich einfach mein eigenes Dialogfragment erstellt, bei dem ich mich aus dem Originalfragment registrieren konnte. Wenn dieses andere Dialogfragment Dinge tat (wie entlassen werden), sagte es allen Zuhörern, dass es verschwinden würde. Ich habe es so gemacht:
Jetzt habe ich eine Möglichkeit, das PlayerListFragment zu benachrichtigen, wenn etwas passiert. Beachten Sie, dass es sehr wichtig ist, dass Sie unregisterPasswordEnteredListener entsprechend aufrufen (im obigen Fall, wenn das PlayerListFragment "verschwindet"). Andernfalls versucht dieses Dialogfragment möglicherweise, Funktionen für den registrierten Listener aufzurufen, wenn dieser Listener nicht mehr vorhanden ist.
quelle
show()
und abfangenIllegalStateException
.onActivityResult()
! Versuchen Sie stattdessen diese Lösung: stackoverflow.com/questions/16265733/…onPostResume
undonResumeFragments
sind beide relativ neue Ergänzungen der Support - Bibliothek.Der Kommentar von @Natix ist ein schneller Einzeiler , den einige Leute möglicherweise entfernt haben.
Die einfachste Lösung für dieses Problem besteht darin, super.onActivityResult () aufzurufen, bevor Sie Ihren eigenen Code ausführen. Dies funktioniert unabhängig davon, ob Sie die Support-Bibliothek verwenden oder nicht, und behält die Verhaltenskonsistenz in Ihrer Aktivität bei.
Es gibt:
Je mehr ich darüber lese, desto mehr verrückte Hacks habe ich gesehen.
Wenn Sie immer noch auf Probleme stoßen, sollten Sie das von Alex Lockwood überprüfen.
quelle
super.onActivityResult()
und sehe leider immer noch die Ausnahme. Wenn ich mir die tatsächliche Implementierung anschaue, ist sie tatsächlich leer (in Fragment.java, v25.0.0), sodass ich nicht sehe, wie sie irgendetwas lösen könnte. Vielleicht ist diese Antwort zu alt, sie hat früher funktioniert, aber nicht mehr?Ich glaube, es ist ein Android-Fehler. Grundsätzlich ruft Android onActivityResult an einer falschen Stelle im Aktivitäts- / Fragmentlebenszyklus auf (vor onStart ()).
Der Fehler wird unter https://issuetracker.google.com/issues/36929762 gemeldet
Ich habe es gelöst, indem ich den Intent im Grunde genommen als Parameter gespeichert habe, den ich später in onResume () verarbeitet habe.
[EDIT] Es gibt heutzutage bessere Lösungen für dieses Problem, die 2012 noch nicht verfügbar waren. Siehe die anderen Antworten.
quelle
onActivityResult()
vorher angerufen wurdeonResume()
EDIT: Noch eine Option und möglicherweise die bisher beste (oder zumindest was die Support-Bibliothek erwartet ...)
Wenn Sie DialogFragments mit der Android-Unterstützungsbibliothek verwenden, sollten Sie eine Unterklasse von FragmentActivity verwenden. Versuche Folgendes:
Ich habe mir die Quelle für FragmentActivity angesehen und es sieht so aus, als würde ein interner Fragmentmanager aufgerufen, um Fragmente wieder aufzunehmen, ohne den Status zu verlieren.
Ich habe eine Lösung gefunden, die hier nicht aufgeführt ist. Ich erstelle einen Handler und starte das Dialogfragment im Handler. Bearbeiten Sie Ihren Code also ein wenig:
Das scheint mir sauberer und weniger hackig zu sein.
quelle
Thread#sleep()
.super.onActivityResult()
ist die einfachste funktionierende Lösung, die es gibt, und es sollte wahrscheinlich die akzeptierte Antwort sein! Ich habe den fehlenden Superanruf zufällig bemerkt und war angenehm überrascht, dass das Hinzufügen einfach funktioniert hat. Dadurch konnte ich einen der auf dieser Seite erwähnten alten Hacks entfernen (den Dialog in einer temporären Variablen speichern und in anzeigenonResume()
).onActivityResult()
kein Wert zurückgegeben wird, der angibt, ob Fragmente das Ergebnis verarbeitet haben oder nicht.Es gibt zwei DialogFragment show () -Methoden -
show(FragmentManager manager, String tag)
undshow(FragmentTransaction transaction, String tag)
.Wenn Sie die FragmentManager-Version der Methode verwenden möchten (wie in der ursprünglichen Frage), besteht eine einfache Lösung darin, diese Methode zu überschreiben und commitAllowingStateLoss zu verwenden:
Das Überschreiben auf
show(FragmentTransaction, String)
diese Weise ist nicht so einfach, da auch einige interne Variablen im ursprünglichen DialogFragment-Code geändert werden sollten. Daher würde ich es nicht empfehlen. Wenn Sie diese Methode verwenden möchten, probieren Sie die Vorschläge in der akzeptierten Antwort (oder im Kommentar von) aus Jeffrey Blattman).Die Verwendung von commitAllowingStateLoss birgt ein gewisses Risiko. In der Dokumentation heißt es "Wie commit (), ermöglicht jedoch die Ausführung des Commits, nachdem der Status einer Aktivität gespeichert wurde. Dies ist gefährlich, da das Commit verloren gehen kann, wenn die Aktivität später aus ihrem Status wiederhergestellt werden muss Daher sollte dies nur in Fällen verwendet werden, in denen es in Ordnung ist, dass sich der UI-Status für den Benutzer unerwartet ändert. "
quelle
Sie können keine Dialoge nach angehängten Aktivitäten anzeigen, die als Methode onSaveInstanceState () bezeichnet werden. Offensichtlich wird onSaveInstanceState () vor onActivityResult () aufgerufen. Sie sollten Ihren Dialog also in dieser Rückrufmethode OnResumeFragment () anzeigen. Sie müssen die show () -Methode von DialogFragment nicht überschreiben. Hoffe das wird dir helfen.
quelle
Ich habe eine dritte Lösung gefunden, die teilweise auf der Lösung von hmt basiert. Erstellen Sie grundsätzlich eine ArrayList von DialogFragments, die auf onResume () angezeigt wird.
quelle
onActivityResult () wird vor onResume () ausgeführt. Sie müssen Ihre Benutzeroberfläche in onResume () oder höher ausführen.
Verwenden Sie einen Booleschen Wert oder was auch immer Sie benötigen, um mitzuteilen, dass zwischen diesen beiden Methoden ein Ergebnis zurückgekehrt ist.
... Das ist es. Einfach.
quelle
Ich weiß, dass dies vor einiger Zeit beantwortet wurde. Aber es gibt einen viel einfacheren Weg, dies zu tun als einige der anderen Antworten, die ich hier gesehen habe. In meinem speziellen Fall musste ich ein DialogFragment aus einem Fragment von onActivityResult () anzeigen. Methode.
Dies ist mein Code, um damit umzugehen, und er funktioniert wunderbar:
Wie in einigen anderen Beiträgen erwähnt, kann das Festlegen eines Statusverlusts zu Problemen führen, wenn Sie nicht vorsichtig sind. In meinem Fall habe ich dem Benutzer lediglich eine Fehlermeldung mit einer Schaltfläche zum Schließen des Dialogfelds angezeigt Zustand davon ist verloren, es ist keine große Sache.
Hoffe das hilft...
quelle
Es ist eine alte Frage, aber ich habe sie auf einfachste Weise gelöst, denke ich:
quelle
Dies liegt daran, dass beim Aufrufen von #onActivityResult () die übergeordnete Aktivität bereits #onSaveInstanceState () aufgerufen hat.
Ich würde ein Runnable verwenden, um die Aktion (Dialogfeld anzeigen) auf #onActivityResult () zu "speichern", um sie später zu verwenden, wenn die Aktivität fertig ist.
Mit diesem Ansatz stellen wir sicher, dass die Aktion, die wir möchten, immer funktioniert
quelle
Die sauberste Lösung, die ich gefunden habe, ist folgende:
quelle
Ich habe diesen Fehler während der
.show(getSupportFragmentManager(), "MyDialog");
Aktivität erhalten.Versuchen Sie es
.show(getSupportFragmentManager().beginTransaction(), "MyDialog");
zuerst.Wenn dies immer noch nicht funktioniert, hilft mir dieser Beitrag ( DialogFragment von onActivityResult anzeigen ), das Problem zu lösen.
quelle
Ein anderer Weg:
quelle
Rufen Sie einfach an,
super.onActivityResult(requestCode, resultCode, data);
bevor Sie das Fragment bearbeitenquelle
Wie Sie alle wissen, liegt dieses Problem daran, dass onActivityResult () vor onstart () aufgerufen wird. Rufen Sie also einfach onstart () beim Start in onActivityResult () auf, wie ich es in diesem Code getan habe
quelle