Belvi Nosakhare
Belvi Nosakhare

Reputation: 3255

Fragment java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first

Starting a fragment as :

public void initFrag(){
    FragmentTransaction transaction = appContext.getSupportFragmentManager().beginTransaction();
                    transaction.addToBackStack(null);

                    transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in,
                            R.anim.fade_out);

                    transaction.replace(R.id.root_frame, uiControlTrier, UUID.randomUUID().toString()).commitAllowingStateLoss();
}

and here's the fragment on createview.

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    if (rootView == null) {
        rootView = inflater.inflate(R.layout.zn_fragment_ui, null);
        if (getArguments().getString(STEP_KEY) == null) {
            getActivity().finish();
        } else {
            initView();
        }
    }
    return rootView;
}

initFrag() can be called from the activity multiple times depending on user selection. Leading to more than one fragment on the backstack.

When I press the back button, the app crashes with :

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
                                                                         at android.view.ViewGroup.addViewInner(ViewGroup.java:4424)
                                                                         at android.view.ViewGroup.addView(ViewGroup.java:4265)
                                                                         at android.view.ViewGroup.addView(ViewGroup.java:4205)
                                                                         at android.view.ViewGroup.addView(ViewGroup.java:4178)
                                                                         at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1425)
                                                                         at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1750)
                                                                         at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1819)
                                                                         at android.support.v4.app.BackStackRecord.executePopOps(BackStackRecord.java:855)
                                                                         at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2587)
                                                                         at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2377)
                                                                         at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2332)
                                                                         at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:851)
                                                                         at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:794)
                                                                         at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:181)
                                                                         at com.appzonegroup.zonesdk.zone.uiEngine.pageRenderer.UIFlowRenderingBase.onBackPressed(UIFlowRenderingBase.java:152)
                                                                         at android.app.Activity.onKeyUp(Activity.java:2730)

I've looked at other thread on fixing this but none has worked yet.

Upvotes: 1

Views: 834

Answers (1)

Eugen Pechanec
Eugen Pechanec

Reputation: 38223

The same problem is very popular when working with FragmentPagerAdapter. If the framework wants you to create something, create it. There's no caching involved.

This method requires you to create a new view.

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)

onCreateView is called when the fragment is first started and after a configuration change, such as screen rotation. In that case the old view needs to be destroyed because it holds a reference to the previous activity which is no longer used (presented to user). Holding onto any view created with old context leads to a memory leak.

If for some reason (somewhere else on your app) you're using application context for inflating views, don't. The activity context has theme information that you want when working with views.

Here are some suggestions:

  1. Leverage the framework, don't work against it.
  2. Optimize only after you have a working piece of code.

Upvotes: 1

Related Questions