Search code examples
androidandroid-activitysavestate

Android SaveInstanceState - Understanding


From this page of Android SDK

The default implementation takes care of most of the UI per-instance state for you by calling onSaveInstanceState() on each view in the hierarchy that has an id, and by saving the id of the currently focused view (all of which is restored by the default implementation of onRestoreInstanceState(Bundle)).

So is there a mechanism that automatically saves the Activity state without saving value from each element in the activity? I am confused about the above statement.

For an example, Activity A invoked Activity B. In Activity B, I have checboxes, Radio Buttons, etc. User select their choices and click Back button. I am showing the Activity At this point, I want to save the user selection. When user again comes back from Activity A to B, by clicking a button, I would like to see all selections persisted. One way I can think of is, setting the Intent Flag to bring the Activity to fore. But not a recommended method, I think.

So is there a default implementation to save the state, per the above text from SDK? Or may be I am interpreting it wrong?


Solution

  • onSaveInstanceState() and onRestoreInstanceState() are only explicitly called by Android when the Activity needs to be recreated, generally after a configuration change (ex. changing orientation). This doesn't cover the case when you have invoked a new instance of the Activity. When you press the back button, Activity B is destroyed, and you are creating a new instance of it the next time you start that Activity.

    If you want to manually save the instance of an Activity, invoke Activity B via startActivityForResult(). Then, in Activity B, override the onDestroy() method, and call these lines of code:

    @Override
    protected void onDestroy() {
    
        Bundle savedState = new Bundle();
        onSaveInstanceState(savedState);
        Intent data = new Intent();
        data.putExtra("savedState", savedState);
        setResult(RESULT_OK, data);
    
        super.onDestroy();
    }
    

    In Activity A, override on onActivityResult and save the data:

    Bundle activityBData;
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK) {
            activityBData = data.getBundleExtra("saved_state");
        }
    }
    

    Then, when starting Activity B again, call it like so:

    Intent intent = new Intent(this, ActivityB.class);
    if (activityBData != null) {
        intent.putExtra("saved_state", activityBData);
    }
    startActivityForResult(intent, 0);
    

    And lastly, in Activity B's onCreate method, restore the state:

    if (savedInstanceState == null) {
        Intent intent = getIntent();
        Bundle savedState = intent.getBundleExtra("saved_state");
        onRestoreInstanceState(savedState);
    }