web-dev-qa-db-de.com

Backstack-Verwaltung: Der Neustarter darf nur während der Initialisierungsphase des Besitzers erstellt werden

Ich verwende eine untere Navigationsleiste in meiner MainActivity, um einige Fragmente zu verarbeiten. Dies ist der Code, der zum Umschalten zwischen ihnen verwendet wird:

private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
    if (item.isChecked &&
        supportFragmentManager.findFragmentById(R.id.act_main_fragment_container) != null
    )
        retu[email protected] false
    val fragment =
        when (item.itemId) {
            R.id.navigation_home      -> fragments[0]
            R.id.navigation_bookings  -> fragments[1]
            R.id.navigation_messages  -> fragments[2]
            R.id.navigation_dashboard -> fragments[3]
            R.id.navigation_profile   -> fragments[4]
            else                      -> fragments[0]
        }
    this replaceWithNoBackStack fragment
    [email protected] true
}

die Methode replaceWithNoBackstack ist hierfür nur eine Abkürzung:

supportFragmentManager
    ?.beginTransaction()
    ?.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
    ?.replace(containerId, fragment)
    ?.commit()

Das Problem ist, dass meine App mit der folgenden Ausnahme abstürzt, wenn ich schneller zwischen ihnen wechsle:

Java.lang.IllegalStateException: Der Neustarter darf nur während der Initialisierungsphase des Besitzers unter androidx.savedstate.SavedStateRegistryController.performRestore (SavedStateRegistryController.Java:59) unter androidx.fragment.app.Fragment.performCreate (Fragment.Java:2580) unter android erstellt werden. fragment.app.FragmentManagerImpl.moveToState (FragmentManagerImpl.Java:837) unter androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState (FragmentManagerImpl.Java:1237) unter androidx.fragment.app.FragmentMan .fragment.app.BackStackRecord.executeOps (BackStackRecord.Java:439) unter androidx.fragment.app.FragmentManagerImpl.executeOps (FragmentManagerImpl.Java:2075) unter androidx.fragment.app.FragmentManagerImpl.ec androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute (FragmentManagerImpl.Java:1820) unter androidx.fragment.app.FragmentManagerImpl.execPendingActions (FragmentMana gerImpl.Java:1726) unter androidx.fragment.app.FragmentManagerImpl $ 2.run (FragmentManagerImpl.Java:150) unter Android.os.Handler.handleCallback (Handler.Java:789) unter Android.os.Handler.dispatchMessage (Handler). Java: 98) unter Android.os.Looper.loop (Looper.Java:164) unter Android.app.ActivityThread.main (ActivityThread.Java:6709) unter Java.lang.reflect.Method.invoke (Native Method) unter com Ich habe viel gesucht und konnte es nicht finden eine Antwort.

Ich habe diesen Fehler auch erhalten, wenn ich einen API-Aufruf durchführe, die App in den Hintergrund stelle, auf die Antwort warte und wenn ich zur App zurückkehre, stürzt die App ab, weil ich versuche, sofort ein Dialogfragment anzuzeigen (der Grund) Ich denke, dies geschieht, weil die Transaktion zum Neuerstellen des Fragments beim Zurückkehren aus dem Hintergrund zum Zeitpunkt der Anzeige des Dialogfragments noch nicht abgeschlossen ist. Ich habe dies auf hackige Weise gelöst, indem ich eine Verzögerung von 500 ms für den Dialog festgelegt habe, da ich keine anderen Lösungen finden konnte.

Bitte fragen Sie, ob Sie diesbezüglich weitere Informationen benötigen. Vielen Dank im Voraus!

MÖGLICHE TEMP-LÖSUNGEN

EDIT Ich habe dieses Problem gelöst, indem ich die App-kompatible Abhängigkeit auf androidx.appcompat:appcompat:1.0.2 herabgestuft habe, aber dies ist nur eine vorübergehende Lösung, da ich sie aktualisieren muss künftig. Ich hoffe, jemand wird es herausfinden.

EDIT 2 Ich habe das Problem gelöst, indem ich setTransition () aus Fragmenttransaktionen entfernt habe. Zumindest kenne ich den Grund, warum Android Apps im Allgemeinen keine guten Übergänge haben

EDIT Die beste Lösung, um dieses Problem zu vermeiden und einen reibungslosen Ablauf zu gewährleisten, ist die Verwendung von ViewPager für die Navigation in der unteren Leiste

19
Gabi

Nichts funktionierte außer Drown Coders Lösung, aber es war immer noch nicht perfekt, da es Transaktionen zum Backstack hinzufügt. Wenn Sie also alle Schaltflächen in der unteren Navigation drücken, befindet sich mindestens 1 von jedem Fragment im Backstack. Ich habe diese Lösung leicht verbessert, sodass Sie .replace() nicht verwenden, das die App mit diesen Animationen zum Absturz bringt.

Hier ist der Code:

if (getChildFragmentManager().getBackStackEntryCount() > 0) {
    getChildFragmentManager().popBackStack();
}

FragmentTransaction addTransaction = getChildFragmentManager().beginTransaction();
addTransaction.setCustomAnimations(R.animator.fragment_fade_in, R.animator.fragment_fade_out);
addTransaction.addToBackStack(null);
addTransaction.add(R.id.frame, fragment, fragment.getClass().getName()).commitAllowingStateLoss();
0

Ich habe dieses Problem bei der Verwendung von setCustomAnimations. durch Entfernen von setCustomAnimations wurde mein Problem gelöst. Außerdem habe ich kein Problem, wenn ich eine neue Instanz eines Fragments erstelle, bevor ich es selbst mit setCustomAnimation zeige.

BEARBEITEN: Eine andere Möglichkeit ist das Hinzufügen von Fragmenten zum Backstack.

0
Hadi Ahmadi