0

I have three activities A, B and C.

A starts B with startActivityForResult(getIntent(), ACTIVITY_B); and B starts C with startActivityForResult(getIntent(), ACTIVITY_C);. ACTIVITY_B and ACTIVITY_C are constants with same value across activities.

When C returns with RESULT_OK, then B is restarted with the code:

if (resultCode == Activity.RESULT_OK){
    finish();
    startActivityForResult(getIntent(), ACTIVITY_B);
}

This works fine.

When B has to return (on clicking a menu item), it sets the activity result.

public boolean onMenuItemSelected(int featureId, MenuItem item) {
    switch(item.getItemId()) {
        case MENU_CONFIRM:
            System.out.println("Setting Result to RESULT_OK");
            setResult(Activity.RESULT_OK);
            finish();
            return true;
    }
    return super.onMenuItemSelected(featureId, item);
}

However I can see that the setResult(Activity.RESULT_OK); is ignored because it is always received as RESULT_CANCEL in the Activity A (onActivityResult). I'm using 2.3.

Any clues?

Venkat Reddy
  • 91
  • 3
  • 7

2 Answers2

0

I am curious how you are handling your Intents and Activity lifecycle.

From what I have read in both of your posts:

  • A starts B with startActivityForResult().
  • B starts C with startActivityForResult().
  • C completes its task, calls setResult() and finish().

Now unless there is something I am missing, Activity B uses this code:

if (resultCode == Activity.RESULT_OK){
    finish();
    startActivityForResult(getIntent(), ACTIVITY_B);
}

to start itself? Could you clarify this?

Addition

I believe you are starting B from B so when you call setResult() and finish() in your second instance of B you are returning to the first B Activity.

If you are not using any special Intent flags the lifecycle will be:

  • A starts B
    • B starts C
      • C finishes
    • B resumes automatically, B finishes
  • A resumes automatically.

From what I understand you have altered that cycle to:

  • A starts B

    • B starts C
      • C finishes
    • B resumes automatically, onActivityResult() starts 2nd B
      • 2nd B finishes, (You expect to see A next, however...)
    • B resumes automatically (If you call finish() again you should see A at this point).

    ...

  • A is waiting in the stack to be resumed.
Sam
  • 86,580
  • 20
  • 181
  • 179
  • I need to restart B because its content needs to be updated when C finishes with RESULT_OK. I don't think the second flow you have mentioned mentioned is what is happening, because when 2nd B starts, the 1st is already finished. I think you missed the finishing of 1st B. So when 2nd B finishes, I expect it to return to A which should see the result as RESULT_OK. – Venkat Reddy Jun 15 '12 at 05:19
  • Also, If, C is not started, all this is working as expected. That is, B returns and A gets RESULT_OK. It is only when C is called, and B is restarted, then the setResult() statement is ignored. I get sysout, indicating the code is being executed but has no effect. – Venkat Reddy Jun 15 '12 at 05:21
  • Is this code block from above `if (resultCode == Activity.RESULT_OK) {...}` in Activity B's onActivityResult()? – Sam Jun 15 '12 at 06:07
0

Don't finish B and start a new one, A will not get notified because it's not the B it opened. Instead, if C needs to return something to B when it ends, create an Intent, put your result values on it, and check this result in B:

C:

Intent data = new Intent();
// Store values you want to return on the intent
setResult(RESULT_OK, data);
finish();

B: in onActivityResult

if (resultCode == Activity.RESULT_OK) {
  // get values from the intent and change B accordingly
}
yoah
  • 7,180
  • 2
  • 30
  • 30
  • Yep. Just figured the issue as you mentioned. It is not the same B which was started by A. I'm fixing this by a different solution which should work for me - I have moved my UI update code into onResume() method with no need to restart B. Still testing it. Thanks!. – Venkat Reddy Jun 15 '12 at 06:09