should I put a big object to onSaveInstanceState() method - android

I am quite new in Android. So, please help me this question.
I have Fragment which I show to user an Email. I put the email content to a Model Object.
Should I put the model object to the bundle in onSaveInstanceState method or how can I persist the model object for Fragment recreate ?
Maybe it is a simple question but please help me.

If you want to save the object in a bundle, it should be a parcelable object. You can use putParcelable and getParcelable for saving and restoring object. Usually it's discouraged to save large data since it will make recreation slower. Only save what you absolutely need.

Related

Singleton vs Bundle to share/pass object from one activity to another

I want to share object from one activity to another activity. I know of 2 good ways:
Using bundle: By making object's class implement Parcelable, can pass object in bundle via intent.
Using singleton pattern: saving the object instance in this class and then fetch it where ever required.
Which of the above mentioned is better or recommended way? Kindly also tell if there is some other better way.
Singleton isn't a good ideia on Activities, because it will produce memory leak (redundancy of information of an Activity).
Parcelable it's a good idea, because you will not use disk IO or Network when you create a local object from a form in the first Activity.
If you retrieve an object from Network or local database, you don't need anyone, because you can retrieve the object in the next Activity.

Best way to keep object reference in Activity through screen orientation changes

The only way that I see is to use a static variable, but it's not okay as I want to keep the ability to start multiple Activites.
In my case, I want to keep a reference of Dagger 2 Component.
It will provide objects like Navigator. I can't just store it into Bundle.
For now, I can't use Retain MainFragment instead of MainActivity because of this bug.(I'm at 23 API level)
Is there any Retain Activity implementation?
Huh, well you have two built in solutions in android to fix this problem:
1) If the object is serializeable or parcelable you can override onSaveInstanceState() and read the value out in onCreate. Here are the google developer docs for the specifics on that.
2) If your object is not serializable you can instead override onRetainNonConfigurationInstance() and return that object. You can then get the object back in onCreate. Look at this SO post for how to use this approach (don't persist your activity though! persist the object.). The drawback of this is that you can only persist one object at a time.
I have a more in depth write up of these two approaches and third, declarative approach that you can roll. It relies on onRetainNonConfigurationInstance and allows you to use annotations to declare what variables in your activity should be persisted. check it out here. That said, I wouldn't recommend using this unless you have more than one non-serializeable/parcelable object to persist.
Edit: clarified point that you shouldn't persist your whole activity using onRetainNonConfigurationInstance().

Passing variable from ViewPager Activity to a Fragment

I'm trying to do this without using a bundle. The reason I am trying to avoid that is because the data is pulled from a database online and I don't want the fragments to not load while it's waiting to get the data. From what I can tell I can only do the bundle arguments if the data is ready to send before any of the fragments are created.
This would cause a problem because the data isn't pulled from the database until the ViewPager is created. I can successfully pass the variables, but like I said the data isn't there instantaneously. This ends up sending a zero value through the bundle variable.
Am I incorrect in assuming you can't still pass bundles after the fragment creation? Aside from Bundles, what would be the best way to send a variable from the ViewPager to the Fragment? Would storing the data in the cache be a good option?
You can setup a method within your fragment to be called from your activity once you have retrieved said data from database. Then within your fragment method you can load it to where ever you need and however you need.
Only thing you have to be concerned about is the static context of the method.
You could cast your Activity to Fragment.getActivity then invoke a getter for your data.
Alternatively, you could use a Loader and implement LoaderManager.LoaderCallbacks in your Fragment to return the data from your database, but only initialize it once the data has been set.
I suppose you could also show some sort of loading Fragment, then replace it with the other after the data is set. You could use a Bundle in that case.
There are lots of ways to solve this. And yeah, the Fragments arguments can't be passed after creation, unless you call Fragment.setArguments before it's attached to the Activity.
Source
Fragment.instantiate
Fragment.setArguments

Android DialogFragment and configuration changes

I'm having some trouble understanding how to make a simple DialogFragment to edit a (complex) object, say a Person, with first and last name, and a list of e-mail addresses each consisting of an enum (Work, Home, etc) and the address.
First of all, how do I properly pass the Person object to a DialogFragment? My current solution has a setPerson(Person person) method, that's called after my DialogFragment is created, but before dialog.show(). This works ok, until a configuration change happens (user rotates the screen). The DialogFragment gets recreated and the reference to my Person object is null. I know I can save the instance using onSaveInstanceState, but the object is complex and expensive, and persisting a large object this way seems wasteful.
I've also tried disabling configuration change in the activity that uses my dialog, and that fixes the problem, but I want the dialog to be reuseable and requiring all the activities that use it to disable configuration changes seems wrong.
Third option would be to save the reference to Person in a static variable, but again, I want the dialog to be reuseable and able to support multiple instances.
How do other people handle their expensive and complex objects in reuseable dialogs?
Well, there are several solutions, none of which are fantastic or failsafe if you are completely unable to serialize the object you're editing.
I don't recommend ever using android:configChanges="orientation" unless it's absolutely, 100% unavoidable. There are other configuration changes, and your app will still break with the others if you resort to using that solution.
But a simple solution that will work in the vast majority of cases is to call setRetainInstance(true) on the DialogFragment. This will prevent your Fragment from being destroyed and re-created on a configuration change. There is an edge-case where this might not work, though. There are other reasons besides configuration changes where the OS will attempt to put an activity or app 'on ice', for example to save memory. In this case, your object will be lost.
The cleanest way to pass a complicated Object to a fragment is to make the Object implement Parcelable, add the object to a Bundle, and pass the bundle to the Fragment with fragment.setArguments(bundle). You can unpack the Object in onActivityCreated() of the fragment by retrieving the bundle through a call to getArguments().
To persist the argument on configuration changes, simply save the "working" parcelable Object to the bundle provided by onSaveInstanceState(Bundle state) method of the fragment, and unpack the argument later in onActivityCreated() if savedInstanceState !=null.
If there is a noticeable performance hit from implementing Parcelable, or you have a "live" object of some kind, one option is to create a non-UI fragment to hold the data object. Without getting into details, you can setRetainInstance(true) on the non-UI fragment and coordinate the connection with the UI fragment through interfaces in the Activity.

How to save lot of object in onRetainNonConfigurationInstance() in android

How do I save a lot of objects in onRetainNonConfigurationInstance() in android like textview with value and webview with value, and then return the object?
Can anybody provide an example?
Thanks
How to save lot of object in onRetainNonConfigurationInstance() in android like textview with value and webview with value .
Your example is invalid. Never pass widgets between activity instances yourself, as you will create memory leaks.
For stuff like WebView, use fragments, and call setRetainInstance(true) on the WebView-hosting fragment. Android will then handle all of the details to keep that WebView in its fragment alive and attach it to the activity created after a configuration change.
For cases where you have more than one object to return from onRetainNonConfigurationInstance(), and they will not introduce memory leaks, use a static inner class, or a java.util collection class, or something as the container for all those objects, and return the container from onRetainNonConfigurationInstance().

Categories

Resources