Android — Send result back through multiple activities finished or not

First the simple case two activities

Let's say you have 2 activities and you want to send back an information such as a value from a form.

ListActivity must create an intent to FormActivity expecting a result.

Then the FormActivity is responsible for sending the result back

And then back to the ListActivity you'll have to override a method called onActivityResult, such as:


Now the complex case: Four activities and one of them killed

Here is the situation I was facing: The app has a flow that some activities would be finished and some would be kept as the user filled the forms.

The problematic flow:

A started B
B started C; B finishes itself
C started D
D sends result to A

So the final stack would be

A -> B(killed) -> C -> D

How to send the result from D back to A?

If no activity was killed, it was a matter of just chaining setResult() and onActivityResult(). However, things are not that simple when you kill an activity in the middle of the process.

So:

Activity A

goToNextActivity(){
startActivityForResult(intentActivityB, SOME_REQUEST_CODE);
}
onActivityForResult(...){
doSomeStuffWithResult();
}

Activity B

goToNextActivity(){
intentActivityC = new Intent(...);
startActivity(intentActivityC);
}

If we only do this, there will be a problem: Since activity B no longer exists, the result we set on activity C will be lost. So the right thing to do is to add this flag (FLAG_ACTIVITY_FORWARD_RESULT), in order to tell the intent that this activity will be finished and removed from the backstack, hence the parent should handle the result.

NOTE 1: if your parent activity will be finished as well, you can use this flag again so the next activity in the stack will handle the result. Due to this reason, you must start the activity with startActivity instead of startActivityForResult (since it won't handle any result as the flag determines)

goToNextActivity(){
intentActivityC = new Intent(...);
intentActivityC.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
startActivity(intentActivityC);
}

Activity C

goToNextActivity(){
intentActivityD = new Intent(…);
intentActivityD;
startActivityForResult(intentActivityD, SOME_REQUEST_CODE);
}
onActivityResult(int reqCode, int resultCode){
if(reqCode == SOME_REQUEST_CODE){
setResult(resultCode);
finish();
}
}

Activity D

goBackToActivityA(){
setResult(someResultCode);
finish();
}

This will send someResultCode to C, which will handle it with the onActivityResult and send it back again with setResult(…) finish();

which will then know by the flag that the activity B no longer exists, hence the activity that should handle it is Activity A, which means the resultCode will finally arrive in the onActivityResultCode of Activity A.