- How many times have you needed to return a result from one
Activity
to another? - A lot of times, actually, I don't remember any app that I've writen without that functionality.
- was that difficult? How did you do it?
- It wasn't, in fact it was pretty easy. Android has a method
startActivityForResult(Intent, int)
that allows us to launch anActivity
waiting for its result in a method calledonActivityResult(int, int, Intent)
, no mistery there. - Well, and what happens when there is more than one
Activity
involved in the process? - ah, it is very easy too, when the second
Activity
of the flow is launched you have to add a the flagIntent.FLAG_ACTIVITY_FORWARD_RESULT
to theIntent
and then it will be your nextActivity
who will be in charge to callsetResult
to deliver the result. - is that all?
- Well, it is not, you need to call
Activity.finish
in the firstActivity
of the flow, else when the user ends in the second one, he will get back to the first one and he will need to click back to leave the flow and receive the result. - That seems a little bit... odd?
- But you can do
Activity.finish
as I said before, in that way when the user finishes the secondActivity
the flow will be finished as well. - and, what happens if the user clicks
back
in the lastActivity
of the flow? - That it leaves the flow.
- But then the user loses all the data provided during the flow, is that right?
- Yes.
- And what if instead of a flow with 2 activities we have a flow with 5, 6 or even 10 activities?
- Then the user would need to start the flow from the beginning.
- Well, that was the point from the beginning, I've also faced that problem and so far, the solution presented below is the one that I like more.
How?
This is very easy and in only a few steps.- First we need to start the first
Activity
of the flow likestartActivityForResult
:
Intent intent = new Intent(this, ProfileNameStepActivity.class); startActivityForResult(intent, PROFILE_REQUEST_CODE_FLOW);
- Then we wait the result like we always do when there is only one
Activity
in the flow.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PROFILE_REQUEST_CODE_FLOW && resultCode == RESULT_OK) { Profile profile = ExtrasUtils.getProfile(data); onProfileCompleted(profile); } else { super.onActivityResult(requestCode, resultCode, data); } }
- Also in the last
Activity
of the flow we add (like always):
Intent intent = new Intent(); intent.putExtra(ExtrasUtils.EXTRA_PROFILE, new Profile.Builder().withName(name).withAddress(address).build()); setResult(RESULT_OK, intent); finish();
So far we haven't done anything special thing, this code we've written hundreds of times.This is the interesting part...- Now we start any other
Activity
involved in the flow withstartActivityForResult
, while this time therequestCode
is not important because we don't wait for it result:
/* We can pass any number less the ones that we listen here, in this case ADDRESS_REQUEST_CODE_FLOW (unless we want to start a sub-flow, I'll explain that later */ Intent intent = new Intent(this, ProfileFinalStepActivity.class); startActivityForResult(intent, 0);
- Finally we need this piece of code in our
BaseActivity
and all our activities will inherit from it.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { setResult(resultCode, data); finish(); } }
This last part of the code is the one that does the magic, if you pay attention, we have started all our activities in the flow withstartActivityForResult
, so when the nextActivity
is finished our activities will receive a call inonActivityResult
, and we do check if we already got a result there from the nextActivity
, so if theActivity
receives the result, we set the result for the currentActivity
and the previous one will do the same until anyActivity
has itsonActivityResult
overriden and it is waiting for therequestCode
.This same technique can be used to include sub-flows inside a flow, imagine for example that the user can do shopping in your application and before the user pays it has to provide some basic info like the name or the address (or a complete profile).The same code that we have used to start/finish a flow, we can use it in any step of the flow to add a sub-flow and it will work just in the same way.What have we achieved with this?
- Now we are able to start/finish a flow in the same place.
- We can deliver a result of a flow (group of activities) very easy.
- We can add additional flows inside a flow easily.
12 de abril de 2016
Android - Flow result instead of Activity result or how to get a result between activities
Etiquetas:
Activity,
Activity Result,
Android,
Development,
FLAG_ACTIVITY_FORWARD_RESULT,
Flow,
Flow Result,
onActivityResult,
Result,
startActivityForResult
Suscribirse a:
Enviar comentarios (Atom)
Thanks! This is the perfect explanation that I was looking for. Everyone was talking about the forward flag but then... what happens when you click back! So I implemented the activityforresult without knowing if it was the good way to go. Thanks!
ResponderEliminarThe Casinos & Casinos Near You (Mapyro)
ResponderEliminarFind the closest casinos and places 청주 출장안마 to go near you 경상남도 출장샵 (mapyro) in New Jersey. 광양 출장안마 광주광역 출장샵 New York City: 6.5/10 · 용인 출장마사지 New York City: 6.5/10.