Dieses Problem ist normalerweise ein Symptom für ein tiefer liegendes Problem mit der Architektur Ihrer App. Sie neigen dazu, es zu sehen, wenn zwischen der Ansichtsebene und der Geschäftslogikebene keine richtige Trennung von Problemen besteht.
Ich kann mir vorstellen, dass Sie eine asynchrone Arbeit direkt in der Aktivität/im Fragment ausführen und dann versuchen, eine Fragmenttransaktion durchzuführen, wenn das Ergebnis zurückkommt.
Es gibt eine Reihe von Dingen, die Sie tun können, um dieses Problem zu lösen:
Verwenden Fragmente nicht
Es gibt so gut wie nie ein Bedürfnis, ein Fragment zu verwenden, - 90% der Zeit, die Sie könnte das gleiche Ergebnis erzielen mit einer ViewGroup und vermeiden Sie alle Life-Cycle-Kopfschmerzen, zufällige Abstürze & sonst erratische Verhalten Fragmente verursachen.
Die einzigen Male, die ich ein Fragment verwenden würde, wenn ich einen spezifischen Lebenszyklus-Rückruf (onActivityResult) benötigte oder wenn ich durch eine dritte Parteibibliothek gezwungen werde (Android Pay, Braintree).
Trennen Sie Ihre Ansicht über eine Schnittstelle
Dies ist im Grunde, was die MVP/MVVM Muster sind alle über. Es trennt Ihre View von Ihrer Geschäftslogik (Presenter/ViewModel). Dies würde Ihnen helfen, weil Ihre Aktivität/Fragment die View-Schnittstelle implementieren würde:
public class MyActivity implements MyView { ...
Wenn Ihre Aktivität beginnt es an den Präsentator bindet und wenn es fertig ist es entbindet:
protected void onCreate(Bundle bundle) {
// ...
presenter.bind(this);
}
protected void onDestroy() {
// ...
presenter.unbind(this);
}
Nun, wenn in Ihrem Unternehmen Logik eine asynchrone Operation beendet und versucht, die Ansicht zu aktualisieren. Wenn die Aktivität beendet ist, ist die Ansicht ungebunden. Sie können es entweder auf Null setzen oder (wie ich es vorziehe) an seiner Stelle eine No-Op-Ansicht haben.
Sie Aktualisiere dein Von der langen Lauf Async Operationen nicht
Wo möglich aktualisieren Sie nicht Ihre Ansicht direkt aus den Ergebnissen eines Asynchron-Prozess mit langer Laufzeit (Netzwerk oder schwere Berechnung).Speichern Sie stattdessen die Ergebnisse in der Persistenzschicht (db/prefs/file). Lassen Sie Ihre Ansicht dann Daten von der Persistenzschicht abonnieren.
Die Subskription kann auf verschiedene Arten erfolgen - RxJava, Event Bus Benachrichtigung, statischer Callback.
Auf diese Weise, wenn das Ergebnis zurückkommt, wird es nur gespeichert. Wenn die Ansicht noch aktiv ist, wird sie benachrichtigt und lädt die Ergebnisse aus der Persistenz. Wenn nicht, kann es sie beim nächsten Mal von dort abholen.
Schließlich
Als Nebenwirkung kann man .commitAllowingStateLoss()
nennen, anstatt nur .commit()
und es wird nicht abstürzen. Das behebt das eigentliche Problem nicht wirklich ...
In welchem Zustand erhalten Sie 'Kann diese Aktion nach onSaveInstanceState nicht ausführen? ' – azizbekian
wenn ich das versuche: fragmentTransaction.beginTransaction(). Replace (R.id.my_frag_cont, fragment) .commit(); – Alexei
Finden Sie die Antworten für diese Frage. Sie geben eine Erklärung für das Problem und mögliche Lösungen. http://stackoverflow.com/questions/7469082/getting-exception-illegalstateexception-can-not-perform-this-action-after-onsa – Juan