[android] How to use onSaveInstanceState() and onRestoreInstanceState()?

I am trying to save data across orientation changes. As demonstrated in the code below, I use onSaveInstanceState() and onRestoreInstanceState(). I try to get the saved value and I check if it is the correct value in onRestoreInstanceState(). But when I try to use the new value in onCreate(), I don't have the new value but the old one.

protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("TEXT", user);

    }
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    savedUser = savedInstanceState.getString("TEXT");
    Log.d("enregistred value", savedUser);

}



public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int display_mode = getResources().getConfiguration().orientation;

        if (display_mode == 1) {

            setContentView(R.layout.main_grid);
            mGrid = (GridView) findViewById(R.id.gridview);
            mGrid.setColumnWidth(95);
            mGrid.setVisibility(0x00000000);
            // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

        } else {
            setContentView(R.layout.main_grid_land);
            mGrid = (GridView) findViewById(R.id.gridview);
            mGrid.setColumnWidth(95);
            Log.d("Mode", "land");
            // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

        }
        Log.d("savedUser", savedUser);
        if (savedUser.equals("admin")) { //value 0
            adapter.setApps(appManager.getApplications());
        } else if (savedUser.equals("prof")) { //value 1
            adapter.setApps(appManager.getTeacherApplications());
        } else {// default value
            appManager = new ApplicationManager(this, getPackageManager());
            appManager.loadApplications(true);
            bindApplications();
        }
}

This question is related to android

The answer is


  • onSaveInstanceState() is a method used to store data before pausing the activity.

Description : Hook allowing a view to generate a representation of its internal state that can later be used to create a new instance with that same state. This state should only contain information that is not persistent or can not be reconstructed later. For example, you will never store your current position on screen because that will be computed again when a new instance of the view is placed in its view hierarchy.

  • onRestoreInstanceState() is method used to retrieve that data back.

Description : 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).

Consider this example here:
You app has 3 edit boxes where user was putting in some info , but he gets a call so if you didn't use the above methods what all he entered will be lost.
So always save the current data in onPause() method of Activity as a bundle & in onResume() method call the onRestoreInstanceState() method .

Please see :

How to use onSavedInstanceState example please

http://www.how-to-develop-android-apps.com/tag/onrestoreinstancestate/


When your activity is recreated after it was previously destroyed, you can recover your saved state from the Bundle that the system passes your activity. Both the onCreate() and onRestoreInstanceState() callback methods receive the same Bundle that contains the instance state information.

Because the onCreate() method is called whether the system is creating a new instance of your activity or recreating a previous one, you must check whether the state Bundle is null before you attempt to read it. If it is null, then the system is creating a new instance of the activity, instead of restoring a previous one that was destroyed.

static final String STATE_USER = "user";
private String mUser;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Restore value of members from saved state
        mUser = savedInstanceState.getString(STATE_USER);
    } else {
        // Probably initialize members with default values for a new instance
        mUser = "NewUser";
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putString(STATE_USER, mUser);
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

http://developer.android.com/training/basics/activity-lifecycle/recreating.html


This happens because you use the savedValue in the onCreate() method. The savedValue is updated in onRestoreInstanceState() method, but onRestoreInstanceState() is called after the onCreate() method. You can either:

  1. Update the savedValue in onCreate() method, or
  2. Move the code that use the new savedValue in onRestoreInstanceState() method.

But I suggest you to use the first approach, making the code like this:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int display_mode = getResources().getConfiguration().orientation;

    if (display_mode == 1) {

        setContentView(R.layout.main_grid);
        mGrid = (GridView) findViewById(R.id.gridview);
        mGrid.setColumnWidth(95);
        mGrid.setVisibility(0x00000000);
        // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

    } else {
        setContentView(R.layout.main_grid_land);
        mGrid = (GridView) findViewById(R.id.gridview);
        mGrid.setColumnWidth(95);
        Log.d("Mode", "land");
        // mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

    }
    if (savedInstanceState != null) {
        savedUser = savedInstanceState.getString("TEXT");
    } else {
        savedUser = ""
    }
    Log.d("savedUser", savedUser);
    if (savedUser.equals("admin")) { //value 0
        adapter.setApps(appManager.getApplications());
    } else if (savedUser.equals("prof")) { //value 1
        adapter.setApps(appManager.getTeacherApplications());
    } else {// default value
        appManager = new ApplicationManager(this, getPackageManager());
        appManager.loadApplications(true);
        bindApplications();
    }
}