Storing and restoring activity states

70 Views Asked by At

When calling another activity, can I be sure that the variable I store in the current activity will be present when it returns?

new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapter, View item, int pos, long id)  {
        Intent i = new Intent(Activity1.this, Activity2.class);
        i.putExtra("position", pos); // 1
        position = pos; // 2
        startActivityForResult(i, REQUEST_CODE); // brings up the edit item activity
    }
});

For the code above, can I use (2) by storing in current activity instance field or should I pass the value using (1) then use getIntExtra() in onActivityResult() to recover that value?

4

There are 4 best solutions below

2
On BEST ANSWER

Ideally you would just save state in Activity1. That way you wont have to pass the variable around through Activity2 and then pass a result (which isn't exactly a result of anything done in Activity2) back to Activity1. To save the value of position in Activity1 you should do the following inside of your Activity:

    private static final String KEY_ARG_POSITION = "KEY_ARG_POSITION";

    private int position;

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

        // Do whatever you are doing in onCreate already...

        if (savedInstanceState != null) {
            position = savedInstanceState.getInt(KEY_ARG_POSITION);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putInt(KEY_ARG_POSITION, position);
    }

This is also relevant if you don't want to lose that value when the screen orientation changes or the OS kills and restarts your Activity.

Lastly, just for the sake of keeping your code organized, unless you need to use the value of position in Activity2, I would recommend not exposing Activity2 to any data that it does not need to manage. If you are working on a large app, these sorts of things can add up and quickly get messy.

2
On

My advice: pass enough information in the Intent to uniquely identify the data item of interest. Do not just pass a position, because positions can change if the order of the items change or other items get added/removed from the list. Imagine a scenario where you pass position 2 to Activity2, but while Activity2 is up, Activity1 reloads its data and position 2 is now some other item.

Also, I would not rely on an instance member of the calling Activity (i.e. the line position = pos in your code). It is possible for your Activity1 to be killed while another activity is the immediate foreground activity. In that scenario, it will be recreated when the result is returned to Activity1, but it will be a new instance of Activity1, so your instance member position will not have the data you set before.

1
On

When using startActivityForResult...you are providing a request code that will be returned in your onActivityResult method. In there you will get the request code, as well as the result code (Sucess, failure, etc. as well as Intent data that you can set from the activity you started.

So you can do:

Intent i = new Intent(Activity1.this, Activity2.class);
i.putExtra("position", pos);
startActivityForResult(i, REQUEST_CODE);

and then in your Activity2 class

Intent intent = new Intent();
intent.putExtras(getIntent().getExtra("position"));
setResult(RESULT_OK, intent);
finish();

which in your first Activity will call:

 onActivityResult(int requestCode, int resultCode, Intent data) {
//Check it's your requestCode,
//Check resultCode == RESULT_OK or whatever you need
//Grab your position from the data intent
}

See https://developer.android.com/training/basics/intents/result.html for more info

0
On

Yes It will present when you return to Activity1 so no need to use getIntExtra. Just store your position in global variable of Activity1.