By default, the retainInstance property of a fragment is false
.
This means it is not retained but is destroyed and re-created on rotation along with the activity that hosts it.
Calling setRetainInstance(true) retains the fragment.
When a fragment is retained, the fragment is not destroyed with the activity.
Instead, it is preserved and passed along intact to the new activity.
When you retain a fragment, you can count on all of its instance variables to keep the same values. When you reach for them, they are simply there.
Let’s take a closer look at how retained fragments work. Retained fragments take advantage of the fact that a fragment’s view can be destroyed and re-created without having to destroy the fragment itself.
During a configuration change, the FragmentManager first destroys the views of the fragments in its list. Fragment views always get destroyed and re-created on a configuration change for the same reasons that activity views are destroyed and re-created: If you have a new configuration, then you might need new resources. Just in case better matching resources are now available, you rebuild the view from scratch.
Next, the FragmentManager checks the retainInstance property of each fragment.
If it is false
, which it is by default, then the FragmentManager destroys the fragment instance.
The fragment and its view will be re-created by the new FragmentManager of the new activity “on the other side” (Figure 25.11).
On the other hand, if retainInstance is true
, then the fragment’s view is destroyed, but the fragment itself is not.
When the new activity is created, the new FragmentManager finds the retained fragment and re-creates its view (Figure 25.12).
A retained fragment is not destroyed, but it is detached from the dying activity. This puts the fragment in a retained state. The fragment still exists, but it is not hosted by any activity (Figure 25.13).
The retained state is entered when two conditions are met:
setRetainInstance(true) has been called on the fragment
the hosting activity is being destroyed for a configuration change (typically rotation)
A fragment is only in the retained state for an extremely brief interval – the time between being detached from the old activity and being reattached to the new activity that is immediately created.
Retained fragments: pretty nifty, right? Yes! They are indeed nifty. They appear to solve all the problems that pop up from activities and fragments being destroyed on rotation. When the device configuration changes, you get the most appropriate resources by creating a brand-new view, and you have an easy way to retain data and objects.
You may wonder why you would not retain every fragment or why fragments are not retained by default. In general, we do not recommend using this mechanism unless you absolutely need to, for a few reasons.
The first reason is simply that retained fragments are more complicated than unretained fragments. When something goes wrong with them, it takes longer to get to the bottom of what went wrong. Programs are always more complicated than you want them to be, so if you can get by without this complication, you are better off.
The second reason is that fragments that handle rotation using saved instance state handle all lifecycle situations, but retained fragments only handle the case when an activity is destroyed for a configuration change. If your activity is destroyed because the OS needs to reclaim memory, then all your retained fragments are destroyed, too, which may mean that you lose some data.
The third reason is that the ViewModel class replaces the need for retained fragments in most cases. Use a ViewModel instead of a retained fragment to persist UI-related state across a configuration change. ViewModel gives the same benefit of retained state across a configuration change without the drawbacks of introducing a more complicated lifecycle for your fragment.
3.145.47.253