wake-up-neo.com

Erhaltene Ausnahme: Fragment bereits aktiv

Ich habe ein Fragment;

MyFragment myFrag = new MyFragment();

Ich setze Daten bündeln auf dieses Fragment:

Bundle bundle = new Bundle(); 
bundle.putString("TEST", "test");
myFrag.setArguments(bundle);

Dann habe ich ersetze altes Fragment mit diesem und setze auf Backstack:

//replace old fragment
fragmentTransaction.replace(R.id.fragment_placeholder, myFrag, "MyTag");
//put on backstack
fragmentTransaction.addToBackStack(null);
//commit & get transaction ID
int transId = fragmentTransaction.commit();

Später habe ich Pop-Backstack mit der obigen Transaktions-ID (transId):

//pop the transaction from backstack
fragmentManager.popBackStack(transId,FragmentManager.POP_BACK_STACK_INCLUSIVE); 

Später setze ich Daten bündeln erneut als Argument für mein Fragment (myFrag):

//Got Java.lang.IllegalStateException: fragment already active
myFrag.setArguments(bundle);

Wie Sie sehen, hat mein oben genannter Code die Ausnahme Java.lang.IllegalStateException: fragment already active. Ich verstehe nicht warummyFragist immer noch aktiv, obwohl ich die Transaktion aus dem Backstack entfernt habe., jedenfalls, da ich die Ausnahme bekam, die ich dachte Ich habe keine andere Wahl, als das Fragment zu deaktivieren. Also habe ich Folgendes getan:

Fragment activeFragment = fragMgr.findFragmentByTag("MyTag");
fragmentTransaction.remove(activeFragment);

Ich bin mir nicht sicher, ob mein oben genannter Code das Fragment wirklich inaktiv kann, da ich nicht gefunden habe, wie ein Fragment inaktiviert werden kann. :(

Wenn ich danach versuche, Bundle-Daten erneut auf mein Fragment myFrag zu setzen, wird immer noch derselbe Fehler angezeigt:

Java.lang.IllegalStateException: fragment already active

Scheint, als hätte ich das Fragment entfernt, es ist immer noch aktiv ...Warum? Wie kann ich ein Fragment deaktivieren?

57
Leem.fin

Das Lesen der setArguments (Bundle args) -Quelle wird Ihnen helfen, Folgendes zu verstehen:

/**
* Supply the construction arguments for this fragment.  This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment.  The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {

    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}

Sie können setArguments (Bundle args) nicht erneut in Ihrem Code auf demselben Fragment verwenden. Was Sie tun möchten, denke ich, ist entweder eine neu Fragment und setze die Argumente erneut. Oder Sie können getArguments () verwenden und dann die put -Methode des Bundles verwenden, um seine Werte zu ändern.

149
Assaf Gamliel

Versuchen Sie, das vorherige Fragment zu entfernen, bevor Sie das neue hinzufügen: https://stackoverflow.com/a/6266144/969325

1
Warpzit

remove () ändert den Fragmentstatus in deaktiv. In Ihrem Fall haben Sie commit () nach remove (..) nicht aufgerufen.

fragmentTransaction.remove(activeFragment);

Sie würden commit () auch nach remove () ausführen.

fragmentTransaction.remove(activeFragment).commit();
1
Joshua

Rufen Sie einfach die öffentliche Methode aus dem Fragment auf

if(userFragment==null){
                    userFragment = new UserFragment();
                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXTRA_CUSTOMER, result);
                    userFragment.setArguments(bundle);
                }else{
                    try {
                        Customer customer = new Customer();
                        customer.parseCustomer(new JSONObject(result));
                        userFragment.updateVeiw(customer);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
0

Zuerst beschreibe ich, warum dies passiert, und dann finde ich die Lösung, die ich gefunden habe.

Dieses Problem tritt auf, wenn Android remove das Fragment vom Stapel ist, aber noch nicht mit dem Entfernen fertig ist. Um dies zu überprüfen, können Sie die isRemoving() -Methode des Fragments verwenden. Wenn false, d. H. Das Fragment nicht aktiv ist, können Sie die Argumente mit setArguments(bundle) festlegen. Andernfalls können Sie keine Argumente für ein bereits aktives Fragment festlegen und es nur überschreiben, indem Sie dieselben Argumente mit getArguments().putAll(bundle) adressieren.

Zusammenfassen,

    if (myFrag.isRemoving()) {
        myFrag.getArguments().putAll(bundle);
    } else {
        myFrag.setArguments(bundle);
    }

Wenn Sie dies vermeiden möchten, dh das Fragment sofort entfernen, damit kein aktives Fragment vorhanden ist, können Sie onBackPressed() in onBackStackChangedListener() verwenden, wodurch die isRemoving() bis false.

0
Ali Nem

Ich habe das gleiche Problem mit Xamarin.Android. Hier ist was die Dokumentation sagt.

Dies kann nur aufgerufen werden, bevor das Fragment seiner Aktivität zugeordnet wurde

0
Jonathan

Hatte das gleiche Problem. Ich habe das Fragment zum Backstack hinzugefügt. Und der Fehler war, dass ich popbackstack () nicht aufgerufen habe. Die Verwendung von Popbackstack hat mir geholfen

0