1

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?

petey
  • 16,914
  • 6
  • 65
  • 97
John Difool
  • 5,572
  • 5
  • 45
  • 80

4 Answers4

1

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

KDeogharkar
  • 10,939
  • 7
  • 51
  • 95
1

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.

jch000
  • 421
  • 3
  • 11
  • I read that `onSaveInstanceState()` needs to be balanced with `onRestoreInstanceState()` while it's not part of the Activity lifecycle and for example `onPause()` won't even call it. – John Difool Jun 09 '16 at 19:00
  • @JohnDifool `onSaveInstanceState()` will be called if the Activity gets killed. `onCreate()` is called when an Activity gets restored. If an Activity is being restored, `savedInstanceState` in `onCreate()` will not equal null, which means you can try to restore any variables that were saved to it. I use this pattern regularly with no issues. Did you get a chance to try it out? – jch000 Jun 09 '16 at 21:41
0

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

egfconnor
  • 2,637
  • 1
  • 26
  • 44
  • This assumes that every time I switch to another Activity I'll have to save all the non-volatile fields I can't recreate from the original activity and pass it back when I call it back, right? – John Difool Jun 09 '16 at 18:56
0

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.

Karakuri
  • 38,365
  • 12
  • 84
  • 104
  • But what is reasonable to save? If I follow your reasoning, I would need to serialize and pass the whole array to the second activity, right? – John Difool Jun 09 '16 at 19:02
  • @JohnDifool depends what you are doing. Why do you need the position of the item instead of something that identifies the item itself? – Karakuri Jun 09 '16 at 23:14