Ich verwende FragmentTransaction.replace()
, um Fragmente ein- und auszuwechseln.
Die App startet das erste Mal ohne Probleme.
Ein IllegalStateException
wird beim Drehen des Geräts aufgrund eines Konflikts zwischen savedInstanceState ausgelöst
und eine neue Fragmenttransaktion ausführen.
Keine AsyncTask ist beteiligt.
Eine StackOverflow-Frage schlägt vor, den Aufruf setContentView()
einzufügen
in onResumeFragments()
, aber das scheint keine Wirkung zu haben. Gleiches mit onPostResume()
.
Eine andere StackOverflow-Frage besagt, dass onConfigurationChanged()
überschrieben werden soll. Dies funktioniert in dem Sinne, dass es nicht zur Ausnahme kommt
weil die Aktivität nicht neu gestartet wird. Dies verhindert jedoch Fragmente mit unterschiedlichem Hochformat
und Landschaftslayouts vom Wechsel zwischen diesen Layouts. Aufruf von setContentView()
in onConfigurationChanged()
verursacht einen ähnlichen Fehler ( IllegalArgumentException: Binäre XML-Dateizeile # 25: ID 0x12345678, Tag null oder übergeordnete ID mit einem anderen Fragment )
Verwendung von fragmentTransaction.commitAllowingStateLoss()
anstelle von .commit()
Ursachen IllegalStateException: Aktivität wurde zerstört .
Wie bekomme ich das zum Laufen?
Weitere Ausnahmebedingungen:
java.lang.RuntimeException: Kann nicht gestartet werden Aktivität ComponentInfo {myapp / myap.MainActivity}:
android.view.InflateException: Binäre XML-Datei Zeile # 25: Fehler Klassenfragment bei myapp.MainActivity.onResumeFragments (MainActivity.java:450)
Verursacht von: java.lang.IllegalStateException: Diese Aktion kann nicht nach ausgeführt werden onSaveInstanceState bei & gt; android.support.v4.app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1533) beim myapp.fragments.FragmentChange.onFragmentChange (FragmentChange.java:128) beim myapp.MainActivity.onNavigationDrawerItemSelected (MainActivity.java:490) beim myapp.fragments.NavigationDrawerFragment.selectItem (NavigationDrawerFragment.java:197) beim myapp.fragments.NavigationDrawerFragment.onCreate (NavigationDrawerFragment.java:78) bei myapp.MainActivity.onResumeFragments (MainActivity.java:450)
Die Reihenfolge im Code beim Drehen des Geräts ist:
%Vor%HauptAktivität:
%Vor%NavigationDrawerFragment
%Vor%FragmentChange
%Vor%Ein stark reduziertes Formular des Projekts auf github , das die IllegalStateException wiedergibt:
Der FragmentManager ist ein
Schnittstelle für die Interaktion mit Fragment-Objekten innerhalb einer Aktivität .
Es scheint mir eine besonders schlechte Idee, es in einem statischen Feld zu speichern und den alten FragmentManager für eine neue Aktivität wiederzuverwenden. Dies führt notwendigerweise zu Aktivität wurde zerstört , wenn die neue Aktivität mit dem Manager aus der alten Aktivität interagiert.
Ersetzen Sie in Ihrem Code
%Vor%von
%Vor% Einige Kommentare :
Ich kann sehen, dass Sie "über und über" hinausgegangen sind, um es zu reparieren (und Stack-Overflow für viele Tipps gescannt haben).
Dein Code funktioniert das erste Mal (auch wenn du in der App startest).
Die Rotation kann das Fragment nicht zum zweiten Mal aufblasen (in activity_main
) und meldet auch den Fehler "commit after save" (das ist seltsam, wie um Himmels willen bekommen wir 2 fatale Fehler? Vielleicht in einem anderen Thread oder " "Save" tötet den Inflator, aber wie kann er weitermachen?).
NavigationDrawerFragment
enthält eine Menge wichtigen Code (der normalerweise in der Activity liegt).
Analysis :
Ihre MainActivity
class extends AppCompatActivity
:
Normalerweise erweitern Sie FragmentActivity
:
Dies liegt daran, dass Sie activity_main
, das eine fragment
enthält, aufblasen.
Vererbung:
Aktivität & lt; - FragmentActivity & lt; - AppCompatActivity & lt; - ActionBarActivity
'& lt; -' bedeutet Vererbung hier.
Ein Grund, warum Sie FragmentActivity speziell in Betracht ziehen müssen, ist, wenn Sie verschachtelte Fragmente (ein Fragment, das ein anderes Fragment enthält) verwenden möchten, da dies in nativen Fragmenten erst ab API Level 17 unterstützt wird
Ich denke, das machst du hier (in activity_main
):
Hier ist eine gute Vorlage App, die Ihr Leben leichter machen sollte:
android-sliding-menu-using-navigation-drawer /
BEFESTIGUNG :
Ersetzen Sie das Fragment in activity_main.xml
durch ListView
.
Ich habe NavigationDrawerFragment
verworfen und etwas Code aus der obigen Vorlage eingefügt und dann bit-by-bit Ihren Code von NavigationDrawerFragment
wieder eingefügt, bis er umfällt.
Es funktioniert jetzt mit Rotation, aber nicht so, wie du oder ich es gerne hätten (Erhalt des Fragmentstatus, NavigationDrawerFragment
einiger Funktionalität), also arbeite ich noch daran.
protrait
Landschaft nach Rotation
Heißer Tipp :
Das .commit
klingt final, nicht wahr? Klingt als ob es synchron wäre? Das ist auch nicht wahr.
Das .commit
setzt die Transaktion in eine ausstehende Warteschlange, um sie wirklich ausführen zu können, benötigen Sie:
Hier ist ein Link zum Fehlerprotokoll des gebuchten Codes bei der Rotation: Linkfehler log
Methode 1. Vermeiden Sie Konfigurationsänderungen. Fügen Sie android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|keyboard"
in Ihrer Manifest-Aktivität hinzu.
Methode 2.
ein. Verpassen Sie als erstes keinen Code von Standard-Orten wie setContentView()
in onConfigurationChanged()
.
b. Ersetzen Sie das Fragment durch das Tag oder durch die ID in XML
c. Ersetzen Sie nicht erneut, wenn das Fragment von ID oder Tag gefunden wurde.
d. Stellen Sie sicher, dass Sie jeden Dailog innerhalb des Fragments onPause
ablehnen.
Tags und Links android android-fragments illegalstateexception