0

In my android app there are 2 activities. I am navigating from activity1 to activity2. I am returining to activity1 by pressing a button in activity2. I want the activity1 to retain the previous state. I am using following code to achieve this.

This code to save the state.

@Override
public void onSaveInstanceState(Bundle savedInstanceState1) {
    super.onSaveInstanceState(savedInstanceState1);
    if (mode == 3) {
        savedInstanceState1.putInt("totscore", totscore);
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                savedInstanceState1.putInt("ballmatrix" + i + "" + j, ballmatrix[i][j][2]);
            }
        }
    }
}

This code to retrieve the state.

@Override
public void onRestoreInstanceState(Bundle savedInstanceState1) {
    super.onRestoreInstanceState(savedInstanceState1);
    // Restore UI state from the savedInstanceState.
    // This bundle has also been passed to onCreate.
    if (mode == 3 && restore == 1) {
        Log.d("ok", "2");
        if (savedInstanceState1 != null) {
            Log.d("ok", "3");
            totscore = savedInstanceState1.getInt("totscore");

            for (int i = 0; i < 6; i++) {
                for (int j = 0; j < 6; j++) {
                    ballmatrix[i][j][2] = savedInstanceState1.getInt("ballmatrix" + i + "" + j);
                }
            }
        }
    }
    drawmatrix();
}

But when retrieving is done, savedInstanceState1 != null turns out to be false everytime. What is wrong here ?

Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
user3293494
  • 609
  • 1
  • 9
  • 21
  • Are you sure that the `mode == 3` is true in the `onSaveInstanceState method` ? Because it seems like the `savedInstanceState` is not saved at all. – G.T. Jun 13 '14 at 18:24
  • it is. bundle saving is done. – user3293494 Jun 13 '14 at 18:29
  • onSaveInstanceState is for saving the state of the current activity into the current activity, not for saving the state of the current activity into the next activity. – Stephan Branczyk Jun 13 '14 at 18:46
  • Please tell us more about your application. Usually if you want to pass data between activities, you need to bundle it, and pass it with the intent. But also, depending on your use case, perhaps you could just eliminate writing a second activity (and just swap out the views inside your initial activity on the press of the button). Conceptually, that second approach would seem to match your mental model a lot more (I would think). – Stephan Branczyk Jun 13 '14 at 18:52
  • @Stephen: He is trying to save the state of the current activity in the current activity not in another activity. All he is trying to do is when he returns back to the current activity, restore whatever he saved from the saved state. – Raghu Jun 13 '14 at 18:54
  • Both the codes are in `activity1`. – user3293494 Jun 13 '14 at 19:00

2 Answers2

0

The answer below was taken from here: onSaveInstanceState () and onRestoreInstanceState ()

onRestoreInstanceState() is called only when recreating activity after it was killed by the OS. Such situation happen when:

  • orientation of the device changes (your activity is destroyed and recreated)
  • there is another activity in front of yours and at some point the OS kills your activity in order to free memory (for example). Next time when you start your activity onRestoreInstanceState() will be called.

In contrast: if you are in your activity and you hit Back button on the device, your activity is finish()ed (i.e. think of it as exiting desktop application) and next time you start your app it is started "fresh", i.e. without saved state because you intentionally exited it when you hit Back.

Other source of confusion is that when an app loses focus to another app onSaveInstanceState() is called but when you navigate back to your app onRestoreInstanceState() may not be called. This is the case described in the original question, i.e. if your activity was NOT killed during the period when other activity was in front onRestoreInstanceState() will NOT be called because your activity is pretty much "alive".

All in all, as stated in the documentation for onRestoreInstanceState():

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

As I read it: There is no reason to override onRestoreInstanceState() unless you are subclassing Activity and it is expected that someone will subclass your subclass.

Community
  • 1
  • 1
crazylpfan
  • 1,038
  • 7
  • 9
0

Simply navigating to another Activity isn't going to destroy the current one. This means when you're launching activity2, activity1 is still in the background (in stopped state, assuming activity2 is full-screen). It has not been destroyed, so all of its state is still around. onSaveInstanceState() is called, in case your Activity does get destroyed. However, unless it has been destroyed, onRestoreInstanceState() will not be called, as your Activity instance is still around -- therefore there is no need to restore state.

If this is just for testing, you can force the Activity to be destroyed when the new one arrives by going to your Developer Options and enabling "Don't Keep Activities". However, what you're seeing is expected behavior. To test that save and restore are working properly, you can either change your device orientation (which will destroy and recreate the activity), or enable the "Don't Keep Activities" option in Developer Options, and launch activity2.

Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
  • So I destroyed `activity1` before navigating to `activity2` using following code. `Intent intent = new Intent(Activity1.this, Activity2.class); startActivity(intent); finish();` Now neither `onSaveInstanceState()` is called nor `onRestoreInstanceState()`. – user3293494 Jun 13 '14 at 18:58
  • That's because you're finishing it. Android won't save the state after you finish it, because finish is the equivalent of throwing it away. You should *not* finish it when launching the new one. – Kevin Coppock Jun 13 '14 at 19:08
  • how else shall i destroy the activity so that activity can be restored. – user3293494 Jun 13 '14 at 19:40
  • You don't have to. The system does it for you. Just call `startActivity(intent)`. Your currently activity will be paused, then stopped, and the new activity will be created and come to the foreground. When you press "back", you'll return to the previous activity. – Kevin Coppock Jun 13 '14 at 20:00
  • by doing this, it is creating new instance of `activity1`. `onCreate()` method is run. I am not getting old state. – user3293494 Jun 13 '14 at 20:04
  • btw `activity1` is having a `surfaceview` which is redrawn. does this make any difference ? – user3293494 Jun 13 '14 at 20:06