I am trying to remove a fragment but very rarely on Crashlytics I am able to see a bug java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager.
I have a separate fragment for fetching user's current location. I use below code to open the fragment.
private void openLocationFragment() {
LocationFragment locationFragment = LocationFragment.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, locationFragment, "location_fragment")
.commitAllowingStateLoss();
}
Now In fragment as soon as i get a location update, I call method onLocationFetched using listener attached to the activity.
Inside this method I remove the fragment using below code.
@Override
public void onLocationFetched(Location location) {
FragmentManager fragmentManager = getSupportFragmentManager();
LocationFragment locationFragment = (LocationFragment) fragmentManager.findFragmentByTag("location_fragment");
if (locationFragment != null) {
fragmentManager.beginTransaction()
.remove(locationFragment) // Here is the exception
.commitAllowingStateLoss();
}
if(location == null){
fetchUserDetails();
}else
fetchCity(location);
}
StackTrace:
Fatal Exception: **java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager.**
Fragment LocationFragment{32a2ed0 (d41fc341-baf2-4266-948a-866fba7e57b5) id=0x7f09028b location_fragment} is already attached to a FragmentManager.
at androidx.fragment.app.BackStackRecord.remove(BackStackRecord.java:316)
at com.avail.easyloans.feature.marketplace.activities.ActivityMarketplace.onFragmentFetched(ActivityMarketplace.java:909)
at com.avail.easyloans.base.fragments.LocationFragment.sendLocationToClient(LocationFragment.java:192)
at com.avail.easyloans.base.fragments.LocationFragment.access$000(LocationFragment.java:46)
at com.avail.easyloans.base.fragments.LocationFragment$4.onSuccess(LocationFragment.java:220)
at com.avail.easyloans.base.fragments.LocationFragment$4.onSuccess(LocationFragment.java:214)
at com.google.android.gms.tasks.zzn.run(zzn.java:4)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6339)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1084)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:945)
What's wrong am I doing here?
I expect that each Activity
is responsible for maintaining its own Fragment
s. This would means that if the Fragment you are trying to access is associated with another Activity
's FragmentManager
, then your app will fail.
I can think of a couple of ways around this, depending on the behaviour you want. If you don't mind having two LocationFragment
s having their own separate lifecycles in two separate activities, you can access them with findFragmentById()
on your FragmentManager
. I.e.:
private void openLocationFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
final Fragment current = fragmentManager.findFragmentById(R.id.fragmentContainer);
if(current == null || !(current instanceof LocationFragment)) {
fragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, LocationFragment.newInstance())
.commitAllowingStateLoss();
}
}
And do the same in your other Activity. Alternatively, you can invoke your other Activity
that hosts the LocationFragment
in onLocationFetched()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With