This article takes a brief look at one of the lesser used Intent flags, Intent.FLAG_ACTIVITY_FORWARD_RESULT.
In Marrow we have a flow, where the user starts a Test and on completion, he has the option to review the answers and his performance.
Summary:
A (with START button) starts BStack looks like: A -> BB backpress -> A (with CONTINUE button)
This is a partial flow of the entire journey of the user. It shows that clicking back from activity B to A, should change the text of button from START
to CONTINUE
.
This seems to a straightforward implementation of chaining setResult()
and onActivityResult()
The complexity comes when we see the entire flow.
Summary:A (with START button) starts B
B starts C
C starts DStack looks like: A -> () -> () -> DD -> A (with REVIEW button)
On clicking back in D, the user should be directly taken to A. So, when B opens C, with startActivity()
it also has to finish()
itself. Something like this,
fun startC() {
val intent = Intent(this, C)
..
startActivity(intent)
finish()
}
Similarly we would have to for C to D.
A can be navigated back either from B (the partial flow) or D (the complete flow). The question is, how do you pass on the result to back to A, which will indicate that user has from D and not from B. Since, we have to finish()
B and C on the way, any setResult()
in D will never be propagated back to A.
This is where the flag Intent.FLAG_ACTIVITY_FORWARD_RESULT
comes into picture. It’s official documentation reads,
If set and this intent is being used to launch a new activity from an existing one, then the reply target of the existing activity will be transferred to the new activity.
Let’s see what it means through an implementation,
So, when B does startActivity()
with flag Intent.FLAG_ACTIVITY_FORWARD_RESULT
, what it means is that, instead of B sending result to A, that responsibility is passed on the next Activity C and similarly, that responsibility is ultimately passed onto D. So, setResult()
will pass on the result back to A.
It’s startActivity() not startActivityForResult()
Notice, the intermediate activities which don’t take responsibility for handling result have
startActivity()
instead ofstartActivityForResult()
. Doing something like,
val intent = Intent(..)
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
startActivityForResult(intent, REQ_CODE)
will result in,
android.util.AndroidRuntimeException: FORWARD_RESULT_FLAG used while also requesting a result
which makes sense, since the only responsibility of the current Activity is pass on the result target from previous Intent.