0

I was reading Handling Configuration Changes docs.

The document advises to use Fragments that have setRetainInstance set to true and then recover the fragment via the fragmentManager's findFragmentByTag method.

My question is that when the activity is destroyed will the fragmentManager survive that? Is it like sharedPreferences where the values stored in it are unaffected by what happens in the activity as long as the values are committed?

Gustavo Gomes
  • 317
  • 5
  • 13
krtkush
  • 1,378
  • 4
  • 23
  • 46

2 Answers2

2

No. When you set setRetainInstance(true) within a fragment's onCreate, (with fragment tag, say "my_fragment"), when your parent activity orientation changes, the android framework stores the instance for the fragment as long as the activity is not destroyed. When you save the fragment tag variable in the parent activity and restore it (see example: https://stackoverflow.com/a/47823139/7152359), you can again call getSupportFragmentManager()... and set the fragment using the tag "my_fragment" that you stored.

In simple words, setRetainInstance(true) is only used to help developers not go through complex/long procedures of onSaveInstanceState(..) and onRestoreInstanceState(..) like many a times developers have to do for activities.

Robillo
  • 192
  • 11
  • To be clear, you're saying that the `fragmentManager` will not survive the config change. Right? Because the activity is destroyed during the process. If this is the case, how am I still able to retrieve my saved fragment when `onCreate` is called again and so is `getFragmentManager`? – krtkush Dec 18 '17 at 06:17
  • 1
    Buddy, there are two different interpretations of onDestroy. Once you override onDestroy () function in the activity, you also can use the function isFinishing() to detect if activity is actually being destroyed (true) of if it's a configuration change (false). The setRetainInstance survives the onDestroy when isFinishing returns false. – Robillo Dec 18 '17 at 06:22
  • I see! Thank you. That explains it. – krtkush Dec 18 '17 at 06:48
0

From my investigations today I believe that FragmentManager does actually survive activity destruction due to configuration changes. This is because if you add a fragment with a tag to the fragment manager (for example, fragmentManager.beginTransaction().replace(R.id.container, myFragment, "blah").commit()), then you can still retrieve that fragment with fragmentManager.findFragmentByTag("blah") even after the activity has been destroyed and re-created due to a configuration change. You can see from the source code that it retains a ArrayList<Fragment> mAdded which contains all of these previously added fragments. If the FragmentManager was destroyed and re-created, this mAdded would have become an empty list, which clearly isn't the case as above.

HOWEVER, the nature of what is retained within each fragment depends on setRetainInstance. If you don't set retain, then only the fragment arguments and saved instance state are persisted, and the fragment instance is re-created by the framework. If you do set retain, then the whole instance (including fields) is persisted. However either way, the FragmentManager itself is still persisted otherwise we wouldn't be able to retrieve tags from it anymore.

While the persistence of FragmentManager across configuration changes is not explicitly mentioned by the documentation, I believe it's implied by statements such as the following:

during a configuration change, your activity and all of its fragments are destroyed and then recreated with the most applicable Android resources. The FragmentManager handles all of this for you. It recreates instances of your fragments, attaches them to the host, and recreates the back stack state.

i.e. if the FragmentManager was not persisted across the configuration change, it could not continue to manage this after activity re-creation.

Adam Burley
  • 5,551
  • 4
  • 51
  • 72