Sounds like you're mixing up two concepts here.
- Saving state across Configuration Changes does not involve serialization. If you request
setRetainInstance()
for aFragment
then that means it will fully stay in memory and not be re-created only for configuration changes. A similar mechanism is available forActivity
objects but they need to explicitly define anObject
which is going to be saved. This works viaActivity.onRetainNonConfigurationInstance()
, not viaonSaveInstanceStae()
. - The other mechanism involves serialization and possibly (maybe not always, not sure) file system I/O to be able to reproduce state information even if an
Activity
/Fragment
is destroyed (which happens independently of its hostingProcess
, btw). This works viaActivity.onSaveInstanceState()
andFragment.onSaveInstanceState()
. - Of course, you can use the second mechanism for the purpose of the first, thus slowing down the way your app deals with configuration changes. Depending on your internal state, the slowdown could me marginal of significant.
Regarding your questions.
- "My Fragment in contrast, is allowed to contain variables which are not serializable." Well, the same is true for your
Activity
. It can contain non-serializable objects which can be saved across config changes as described above. - "the fragment cannot be stored to disk when a process is shut down and must be recreated when an activity was restored." No, both mechanisms are available for both object types.
Hope I could contribute to clarifying this a bit.
Edit after your first comment.
Regarding the comment:
- "
onRetainNonConfigurationInstance
is deprecated": Yes. I mentioned it for demonstration purposes because of a specific wording in your question. Also, with Android 2 devices having a 46% market share as per today (official Google figures), this method will definitely stay around for a very long time, deprecated or not. - "My main concern is about what will happen to the fragment instance when my hosting process is killed and removed from the memory": Your fragment instance will be removed from memory and there's of course no way it is restored as-is with its complete internal state automatically. This is only done when you
setRetainInstanceState
in the case of config changes. (But note that this relates to the Instance, in other words, the full object.)
Regarding your edit:
- Once more, yes, your
Fragment
'sBundle
will be stored and restored to/from theBundle
regardless ofsetRetainInstanceState
if you useFragment.onSaveInstanceState()
for this purpose, for everything that makes sense. - It is not true that "all of its visible state" will be saved as the text you refer to claims; for example, the
visibility
attribute will not be saved. Whether that's supposed to be a bug or a feature I don't know, but it's a fact. But this is only a side remark; UI elements will save most of their relevant state. - "the state of the process is written to the file system": No! The state of objects which are able to save their state to a
Bundle
and actually implement saving their state will be saved in aBundle
, this means that you must provide such information yourself if you want yourFragment
to save some state information. Also, again: No, this does not only relate to killing the process but also to deletingActivity
andFragment
objects which are not visible; like the last Activity shown -- theProcess
may well stay alive. - "bundles are read for resuming the process": No, the
Bundle
will be read to pass it to the re-construction of Activity and/or Fragment objects, there is nothing done automatically in this process (except library objects which save their state also restore their state), but Android does not "resume" the "Process" from theseBundle
s. - "Since the retaining of fragments is not concerned with life cycle methods": Again, I think you're mixing up the two concepts. The "retaining" of a
Fragment
is only performed upon configuration changes _IF_ you request it viasetRetainInstance
, but we're mostly talking about the re-creation ofFragment
objects from aBundle
here, which does involve the life cycle methods as documented by Google. - "I would not know how to retain e.g. a pointer to a network connection": Again, this must be a statement based on your mix-up. Of course you can keep a reference to a network connection upon config change (as requested per
setRetainInstance
) because when that happens, everything is simply kept in memory. Also, even if yourFragment
gets deleted (because it became invisible) and your process is still there (because it shows the next Activity), you can (and should) keep references to objects which are expensive to re-create, such as a network connection, in yourApplication
object, which exists as long as your process lives (more or less). It is only when your whole app is killed by Android that you lose everything, but the serialization we're discussing happens much more often.
Your conclusion:
I concluded that they surely needed to be recreated and that the life cycle methods are therefore to be preferred over setRetainInstance(true) whenever possible. Does this assumption make any sense?
Unfortunately not, since you are mixing up completely independent concepts.
I'll give it a final try:
- You will want to keep a network connection reference which you need throughout your app in your
Application
object because it would be a lousy user experience if you created it from scratch on a regular basis throughout your app. - Your
Application
object will only die if Android kills your app. - Your
Activity
andFragment
objects will be deleted from your app regularly when the user moves forward within your app. - When the user presses "back", Android will re-create
Activity
andFragment
objects fromBundle
s using lifecycle methods. Saving something in a Bundle makes sense if you have expensive computations to do to re-create the internal state. You can live without theBundle
mechanism because Android will always save theIntent
so if you don't do anything then you'll start without saved state. - When a configuration change occurs, Android lets you optimize user experience by keeping objects in memory across the config change. Here,
Activity
life cycle methods get involvwed and it's up to your implementation to use the saved data effectively. ForFragment
s, this is wheresetRetainInstance' comes into play: Your
Fragment` will survive the config change in memory if you set it.