Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `onRetainCustomNonConfigurationInstance` to retain data across configuration changes

Tags:

I've been programming for Android for some time, and I'm still looking for solutions to retain data over configuration changes. Aside from saving Parcelables to Activity's Bundle in onSaveInstanceState docs are suggesting using Fragment with setRetainInstance flag set to true.

But I've just come across some code that uses onRetainCustomNonConfigurationInstance to hold arbitrary objects (in a fancy way, but essentially big objects without references to Activity etc.). I have never seen this method used, so I have some doubts:

  • Is this method safe to call to store arbitrary objects (in a sense that I can be pretty sure it's gonna get called, and that it won't be deprecated/removed anytime soon)?
  • How is this method different from onRetainNonConfigurationInstance(), which also should return Object, and in essence should work similarly?
  • Is using retained fragment still better, for some reason?

As a bonus, I would be grateful for any other tips or solutions to save state of objects like AsyncTask, Observable, view's presenters and go on

like image 680
wasyl Avatar asked Jun 05 '15 18:06

wasyl


People also ask

How to handle configuration changes in Android?

If you want to manually handle orientation changes in your app you must declare the "orientation" , "screenSize" , and "screenLayout" values in the android:configChanges attributes. You can declare multiple configuration values in the attribute by separating them with a pipe | character.

What are configuration changes?

A configuration change occurs when you modify component information that is subject to change control. You can apply change control to specific component fields and classification attributes. The fields and attributes that you designate for change control are collectively referred to as configuration information .


1 Answers

Is this method safe to call to store arbitrary objects (in a sense that I can be pretty sure it's gonna get called, and that it won't be deprecated/removed anytime soon)?

onRetainCustomNonConfigurationInstance() is a relatively new method and it is not deprecated. I would really assume it is not going to disappear soon, because there is no reason for introducing something new just to remove it. You can use it safely.

How is this method different from onRetainNonConfigurationInstance(), which also should return Object, and in essence should work similarly?

onRetainNonConfigurationInstance() always return an instance of inner NonConfigurationInstances class with retained fragments, loaders etc states. You cannot (and should not) change this system behavior. That's why the method is final and you cannot override it.

If you want to retain your custom instance, you need to override onRetainCustomNonConfigurationInstance() and return it from there.

In fact, onRetainNonConfigurationInstance() calls onRetainCustomNonConfigurationInstance() and retains retuned instance with the other states like retained fragments and loaders.

Is using retained fragment still better, for some reason?

It is rather a matter of your use case and preferences. The logic might be like this. If your activity just controls fragments and has no other special logic in it, then it is easier to use retained fragments. If your activity has something to retain, then you can safely use onRetainCustomNonConfigurationInstance() method. As for now, in both cases the state still gets retained by good old and deprecated onRetainNonConfigurationInstance() method.

p.s. Regarding the bonus question about storing a state I would rather suggest to look at onSaveInstanceState() method. It was intended for storing states.

Update: AndroidX release from November 5, 2018 deprecated the method with the following note: onRetainCustomNonConfigurationInstance has been deprecated. Use a ViewModel for storing objects that need to survive configuration changes.

like image 106
sergej shafarenka Avatar answered Oct 26 '22 18:10

sergej shafarenka