Activity/Fragment Purge and Restore Best Practices
Android has a very odd lifecycle for apps, activities, and fragments. Its well defined, but odd.
First Thing to Understand
- When an activity is stopped it also stops its fragments.
- Activities that are NOT on the top of the back-stack (invisible to the user), can be destroyed at any time. This includes the top-most activity if the app is in the background.
- When an activity is destroyed it also destroys its fragments, including ones that were marked with
- After destruction Android will auto create an activity as needed.
- When auto-created, an activity also auto creates and attaches all added fragments. This feels a bit odd, but there is an easy pattern to follow.
- Since an activity’s layout is destroyed and recreated, the fragments will auto re-attach to the new layout. The fragments are attached using the view’s id. If the layout is dynamically generated then YOU must reuse the ORIGINAL view-id’s. This allows android to reattach each fragment to the right container.
- The member variables of activities and fragments are NOT restored after they are auto-created.
- Fragments MUST be scoped publicly. Inner Fragments MUST be also be defined statically. Fragments MUST have a public default constructor (just don’t create one as private).
What follows from this
- Activities and even fragments are NOT a good place to hold long term data. Long term data should be held in a persistent Singleton (e.g. a “manager”), cache, or simply be able to be re-fetched or recreated. Use Activity.onSaveInstanceState and Activity.onCreate to store and restore simple member variables — complex data is better stored in singletons, cache, etc.
- Since member variables are not restored you need to take care to do this yourself.
- All memory variables need to be initialized or restored in one of the onCreateXXX or onStart methods (Activity.onCreate, Activity.onCreateView, Activity.onStart, Fragment.onCreate, Fragment.onCreateView, Fragment.onActivityCreated, Fragment.onStart).
- This requirement is quite burdensome.
setRetainInstance()is only helpful to make screen rotations quicker.
- Every screen must deal with the activity and fragment destruction and restoration issue.
- Android is free to kill the app’s process at time its not in the foreground. Even if it is in foreground, it can still be killed but priority would be least.