An exception occurred while trying to save the state of the attached fragment [The fragment no longer exists for the key android: target_state]

To focus on the problem, I will simplify this matter: I have activity A and fragment F , which adds another fragment of the Child . The simplified code for each of them is

Activity A

@Override protected void onCreate(Bundle savedInstanceState) { // do some stuff FragmentManager fm = getSupportFragmentManager(); F f = new F(); fm.beginTransaction() .add(R.id.content, f) .commit(); } 

Fragment F

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // do some stuff FragmentManager fm = getChildFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); ChildFragment childFragment = new ChildFragment(); childFragment.setTargetFragment(this, 1); transaction.add(R.id.f, childFragment); transaction.commit(); return view; } 

The code of the child fragment is not related to the problem, so I will not publish it.

Using this code, everything seemed to work correctly until I turned on Firebase and started getting the next crash report

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.test/com.test.test.A}: java.lang.IllegalStateException: Fragment no longer exists for key android:target_state: index 1 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429) at android.app.ActivityThread.access$800(ActivityThread.java:151) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5341) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641) at dalvik.system.NativeStart.main(Native Method) 

At first I could not throw an exception, but after testing for a while I found that if the developer option Do not perform actions is enabled, this happens almost every time I transfer activity to the background and resume it. I think that in the normal case this will happen when the action is placed in the background and the application is destroyed.

After doing some research, I came to the conclusion that the actual cause of the failure is that fragment F is specified as the target fragment for it. I can confirm that if I do not set the target fragment, the accident does not occur.

I’m not sure, but it seems that the cause of the accident is that the Child fragment and its target fragment are in different FragmentManagers. Therefore, the first thing I tried was to place all the fragments in the activity fragment manager.

Fragment F

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // do some stuff // I do not want to use private fragment manager but rather use the activity's // FragmentManager fm = getChildFragmentManager(); FragmentManager fm = getFragmentManager(); // do the other stuff } 

This solved the problem. But lead to another. When I delete a fragment from an action (I want to replace it with another fragment). The child fragment was not able to save its state, because it has a link to its parent fragment, which has been deleted from the manager.

 Process: com.test.test, PID: 11047 java.lang.IllegalStateException: Failure saving state: ChildFragment{423c10f0 #1 id=0x7f0b0058} has target not in fragment manager: F{423c0f88} at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:2618) at android.support.v4.app.FragmentController.saveAllState(FragmentController.java:134) at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:571) at android.support.v7.app.AppCompatActivity.onSaveInstanceState(AppCompatActivity.java:515) at android.app.Activity.performSaveInstanceState(Activity.java:1157) at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1229) 

I can try to go deeper and remove the child fragment when its parent is deleted, but I have the feeling that this is the wrong way to do this, because I think the right way to do this is to use getChildFragmentManager (),

Any help, suggestions, recommendations on this topic will be greatly appreciated.

+6
source share
1 answer

I changed my code like this and it works for me, Change ActivityA like this,

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity); FragmentManager fm = getSupportFragmentManager(); if (fm.findFragmentById(R.id.content) == null) { F f = new F(); fm.beginTransaction() .add(R.id.content, f) .commit(); } } 

And you can use your previous implementation, such as setTargetFragment for the ChildFragment fragment. This resolved the first exception you mentioned in the question.

+3
source

Source: https://habr.com/ru/post/1014217/


All Articles