1

It is quite common to use headless fragment technique (fragment with setRetainedInstance(true)), to let long running task deal with UI updating.

https://stackoverflow.com/a/12303649/72437

public class UIFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        headlessFragment = (HeadlessFragment)fm.findFragmentByTag(HEADLESS_FRAGMENT);

        if (headlessFragment == null) {
            // This happens during UIFragment first-time creation.

            headlessFragment = HeadlessFragment.newInstance();
            headlessFragment.setTargetFragment(this, 0);
            fm.beginTransaction().add(headlessFragment , HEADLESS_FRAGMENT).commitAllowingStateLoss();
        } else {

            // UIFragment is having configuration change.
            // UIFragment is being re-created.
            // Make sure headlessFragment is having latest instance of UIFragment.
            headlessFragment.setTargetFragment(this, 0);
        }
    }
}

I'm using support library.

Many years back, when UIFragment re-creation happen, the following code snippet is essential, to ensure headless fragment is having reference to latest UIFragment instance.

// UIFragment is having configuration change.
// UIFragment is being re-created.
// Make sure headlessFragment is having latest instance of UIFragment.
headlessFragment.setTargetFragment(this, 0);

However, today when I re-test the code, using latest support library v7:25.0.0, I realize such code isn't necessary anymore. I can wrote it in

public class UIFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        headlessFragment = (HeadlessFragment)fm.findFragmentByTag(HEADLESS_FRAGMENT);

        if (headlessFragment == null) {
            // This happens during UIFragment first-time creation.

            headlessFragment = HeadlessFragment.newInstance();
            headlessFragment.setTargetFragment(this, 0);
            fm.beginTransaction().add(headlessFragment , HEADLESS_FRAGMENT).commitAllowingStateLoss();
        } else {
             // UIFragment is being created.
             //
             // Event without calling headlessFragment.setTargetFragment,
             // headlessFragment.getTargetFragment will *magically* 
             // return latest instance of UIFragment.
        }
    }
}

First, I suspect, in latest support library, the headlessFragment.setTargetFragment is being called automatically during UIFragment re-creation.

However, when I try to confirm, by overwriting headlessFragment.setTargetFragment with some logging, I realize it is not being called during UIFragment re-creation.

May I know, how does headlessFragment able to get the latest re-created UIFragment, magically?

Community
  • 1
  • 1
Cheok Yan Cheng
  • 49,649
  • 117
  • 410
  • 768

0 Answers0