A challenge commonly faced when first developing in Android is the potentially frequent destruction and reconstruction of an Activity. The most common time this occurs is when the user rotates the device between horizontal and portrait orientations.
Many an app that runs fine during testing suddenly crashes when put into a user’s hands simply because the user tilted the device one way or another.
This crashing usually occurs because device orientation changes cause the Android framework to tear down the displayed Activity along within any contained Views, and then to fully reconstruct the Activity/View hierarchy. Any references to the Activity or to the Views within the Activity suddenly become invalid. Similarly any references within the Activity or Views that were set as a result of a user action or similar are now lost.
There are a number of ways to deal with this issue but one of the easiest is to take advantage of Fragments.
NOTE: You can use the configChanges attribute on your Activity’s manifest entry to prevent the teardown/reconstruction process caused by orientation changes but that has its own headaches.
Fragments won’t automatically resolve this issue because, by default, when the Activity is torn-down in response to an orientation change the Fragment contained within the Activity is also torn down along with any contained Views.
The solution lies in an underused method: Fragment.setRetainInstance.
Calling setRetainInstance with a value of true causes Android to preserve the Fragment across the teardown/reconstruction cycle of an Activity. Along with the Fragment, the Views or other object references contained within the Fragment or Views remain.
With setRetainInstance(true) called on a Fragment instance … when an orientation change occurs, Android…
- Holds a reference to the Fragment instance
- Tears down the old Activity instance
- Creates a new Activity instance
- Attaches the preserved Fragment instance to the new Activity instance
With that, the Fragment, contained Views and object references, remain intact.
Something to keep in mind though … because your Fragment instance will be moved between different Activity instances, you should avoid caching a reference to the Activity. Instead call Fragment.getActivity anytime you need to reference the Activity.
Jim talks more about Fragments in his Pluralsight course…