37

How to save Object while orientation change, since onRetainNonConfigurationInstance and getLastNonConfigurationInstance are deprecated. And which cannot me used with compatibility package android-support-v4.jar FragmentActivity, where it shows Cannot override the final method from FragmentActivity

developer site say

Use the new Fragment API setRetainInstance(boolean) instead;

But I don't know how to save a custom object using setRetainInstance

My scenario :
In my activity I have a AsyncTask with progress dialog. Here I need to handle orientation change.
For that I got a very good answer from Mark Murphy, CommonsWare
background-task-progress-dialog-orientation-change-is-there-any-100-working,
with sample project

Since I'm using compatibility package android-support-v4.jar, FragmentActivity, I can't override onRetainNonConfigurationInstance
Cannot override the final method from FragmentActivity

Is there any alternative method for saving my custom object?

EDIT: I cannot make my AsyncTask task Parcelable (If I'm not wrong) since it use interface, context etc. My AsyncTask

 public class CommonAsyncTask extends AsyncTask<Object, Object, Object>  {
        Context context;
        AsyncTaskServices callerObject;
        ProgressDialog progressDialog;
        String dialogMessag ; 
    ................

I'm looking, is there any alternatives for onRetainNonConfigurationInstance method, which save an object completely while orientation change and later can be retrieve using getLastNonConfigurationInstance

Community
  • 1
  • 1
Labeeb Panampullan
  • 34,521
  • 28
  • 94
  • 112

4 Answers4

43

You can use onRetainCustomNonConfigurationInstance.

Use this instead of onRetainNonConfigurationInstance(). Retrieve later with getLastCustomNonConfigurationInstance().

Giorgi
  • 30,270
  • 13
  • 89
  • 125
  • That's just the same as `onRetainNonConfigurationInstance()` which the questioner is explicitly trying to avoid (in the first sentence of the question no less!) – Timmmm Oct 29 '12 at 11:01
  • 5
    No, it's not the same. See docs: http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html#onRetainCustomNonConfigurationInstance\(\) The OP did not say that he was trying to avoid using onRetain...(), he just said it wasn't compiling since it has been declared final in the support lib (which is all true). I think this solution is valid as a holdover / workaround while migrating to the new way of doing things. – greg7gkb Nov 09 '12 at 00:51
  • 16
    Sometimes I feel these APIs were made more complicated then they should be. – Phillip Jul 23 '13 at 02:04
12

There are two alternatives:

  1. Use a Loader. The FragmentActivity will take care of saving/restoring its state when re-creating.
  2. Use a fragment without a view and call setRetainInstance(true) on it. There is an example of this in the compatibility library's source, FragmentRetainInstanceSupport or some such.
Timmmm
  • 88,195
  • 71
  • 364
  • 509
Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
  • Thanks Nikolay Elenkov for directing me to `loader`, after a big fight I have done it using `loader` inside a `fragment` – Labeeb Panampullan Oct 11 '11 at 04:46
  • Could you tell me how you handled the show/dimiss of the progress dialog since these fragment transactions are forbidden in onLoadFinished? – denis May 02 '12 at 13:44
  • Use `FragmentTransaction.commitAllowingStateLoss()`. Sounds dirty, but there seems to be no other way. Or, better yet, don't use a progress dialog. Use the action bar spinner (indeterminate progress) or something else. Dialog are usually not worth the trouble. – Nikolay Elenkov May 02 '12 at 13:52
  • Interesting. Has this been added recently? I don't remember seeing it before. – Nikolay Elenkov Jun 25 '12 at 01:02
  • @NikolayElenkov Is this not appropriate if your fragment does have a view? – David Doria Sep 30 '13 at 14:28
5

When your Fragment is paused it will call this method:

@Override
public void onSaveInstanceState(Bundle outState) {
    // Add variable to outState here
    super.onSaveInstanceState(outState);
}

The variable outState will then be fed into the onCreate() method when the Fragment restarts.

You can save any data that is a basic type or implements Parcelable interface

Graeme
  • 25,714
  • 24
  • 124
  • 186
-1

Well, quote from Android Developers' References:

This method is called after onStart() when the activity is being re-initialized from a previously saved state, given here in savedInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle).

Regarding the use of onSaveInstanceState(), it's better to revert your objects/things by using onRestoreInstanceState() instead.

Refer to Activity#onRestoreInstanceState()

Reno
  • 33,594
  • 11
  • 89
  • 102
Pete Houston
  • 14,931
  • 6
  • 47
  • 60
  • See my edit, I cannot make my AsyncTask task Parcelable (If I'm not wrong) since it use interface, context etc.. to use with `onSaveInstanceState` – Labeeb Panampullan Oct 06 '11 at 13:56
  • `onRestoreInstanceState()` is not a replacement for `onSaveInstanceState()` - infact it is entirely useless without it. The quote merely mentions in some instances it is more convenient to use `onRestoreInstanceState()` over `onCreate()`. – Graeme Oct 23 '12 at 10:37