I\'ve got a monkey crash whereby
java.lang.IllegalStateException: Failure saving state: FragmentB has target not in fragment manager: FragmentA
at android.s
There are actually two things you should do to resolve this issue:
1. Make sure you use getChildFragmentManager() NOT getFragmentManager() when launching FragmentB from FragmentA
Calling getChildFragmentManager() will return the hosting Fragment's FragmentManager, whereas getFragmentManager() will return the hosting Activity's FragmentManager. It's important to use getChildFragmentManager() because you're nesting a Fragment inside another Fragment, so the parent Fragment should be in charge of handling any transactions with the nested Fragment. If you use getFragmentManager(), you'll run into the issue you're experiencing right now.
2. DO NOT use setTargetFragment() and getTargetFragment(), they will not work when using getChildFragmentManager()
Instead, use getParentFragment(). I believe there is some kind of bug in Android right now where even if you properly call
fragmentB.setTargetFragment(fragmentA, 0);
and then show FragmentB, after a configuration change, calling getTargetFragment() from FragmentB will return itself instead of FragmentA.
I just faced this problem and this is what I think is happening and how I fixed it:
Your FragmentA instance is being destroyed and another one is being created when there is a device rotation, for example. When this happens, your FragmentB keeps holding a reference to a FragmentA which doesn't exist anymore.
In this case, you have to reset FragmentB's target to be the new FragmentA instance.
I did that with the following code in FragmentA:
@Override
public void onAttach(Context context) {
super.onAttach(context);
FragmentB fragment = (FragmentB) getFragmentManager().findFragmentByTag(FragmentBtag);
if (fragment != null) {
fragment.setTargetFragment(this, 0);
}
}
This way, whenever the FragmentA is attached to the Context, ie: a device rotation happens, FragmentB's target is reset, if FragmentB was created at first hand (if so, it would be on FragmentManager).
I hope it helps.
In my case the issue was about calling setTargetFragment
on wrong Fragment.
Was:
FragmentA.setTargetFragment(FragmentB);
Should be:
FragmentB.setTargetFragment(FragmentA);
Here's a workaround:
put this in the fragment that causes the problems:
@Override
public void onSaveInstanceState(final Bundle outState) {
setTargetFragment(null, -1);
...
and remember to set it to the real target fragment when you need it.
We ran into this issue recently. We have implemented a custom adapter extending android.support.v4.app.FragmentStatePagerAdapter. With android.support.v4.app.FragmentManager, we have set up several fragments in the pager, as well as several other fragments outside of the pager. The fragments are managed in a single activity. There are some instances where we were setting the target (with setTargetFragment) of non-paging fragments to fragments that may or may not be contained in the paging adapter. Because FragmentStatePagerAdapter only maintains a certain number of fragments, the fragments that were set as targets and what FragmentStatePagerAdapter deemed no longer needed, were destroyed...and a potentially inconsistent state if the fragments that had those targets still existed. This led to the exception being thrown whenever the app lost focus (either when the screen turned off or the app went into the background), i.e., when onSaveInstanceState was called.
To prevent this exception, in onSaveInstanceState, we checked to see what fragments were currently in the fragment manager. If there were any inconsistencies (i.e., a "target" fragment was missing), we removed the fragment that had that target set. In our case, we only had three fragments where we were setting a target so we knew exactly what to look for.
I don't believe there is any other way to handle this case, but if anyone has any helpful feedback, it would be much appreciated.
Be sure that you've added both fragments to the backstack!
I just ran into this issue when adding a new 'called' fragment for result on top of a 'target' fragment. Initially, I was getting the same error, which stopped occurring as soon as I added both fragments to the back stack whenever I used them.
The issue occurred on screen rotations, so it was easy to reproduce.