I have activities A -> B -> C -> D. How can I open the existing B from activity D clearing C and D? I would end up with A -> B. I don't want to recreate a new B.
I think you must use FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP.
According to the doc:
consider a task consisting of the activities: A, B, C, D. If D calls
startActivity() with an Intent that resolves to the component of
activity B, then C and D will be finished and B receive the given
Intent, resulting in the stack now being: A, B.
The currently running instance of activity B in the above example will
either receive the new intent you are starting here in its
onNewIntent() method, or be itself finished and restarted with the new
intent. If it has declared its launch mode to be "multiple" (the
default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same
intent, then it will be finished and re-created; for all other launch
modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be
delivered to the current instance's onNewIntent().
You can declare you target activity's(Activity B in your situation) Mode of SingleTop in Manifest file like
<activity android:name="YourActivityName" android:launchMode="singleTop"></activity>
Then startActivity for navigating to this Activity will end C and D and wont start a new Activity B
Right after you finish dealing with C and D, you can just finish() the activities.
Related
Is it possible to clear all previous activities only in this current task?
So, my stack of activities looks like this:
A - B - (NEW_TASK) - C - D - E
Is it possible to launch E with some flag:
A - B - (NEW_TASK) - C - D - (SOME_FLAG) - E
which will remove both activities C and D (all previous activities in current task), so after clicking Back in activity E app will return to the place where the new task was started (Activity B)? After starting activity E, the back stack should be like this:
A - B - E
FLAG_ACTIVITY_CLEAR_TOP
If set, and the activity being launched is already running in the
current task, then instead of launching a new instance of that
activity, all of the other activities on top of it will be closed and
this Intent will be delivered to the (now on top) old activity as a
new Intent.
For example, consider a task consisting of the activities: A, B, C, D.
If D calls startActivity() with an Intent that resolves to the
component of activity B, then C and D will be finished and B receive
the given Intent, resulting in the stack now being: A, B.
The currently running instance of activity B in the above example will
either receive the new intent you are starting here in its
onNewIntent() method, or be itself finished and restarted with the new
intent. If it has declared its launch mode to be "multiple" (the
default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same
intent, then it will be finished and re-created; for all other launch
modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be
delivered to the current instance's onNewIntent().
This launch mode can also be used to good effect in conjunction with
FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task,
it will bring any currently running instance of that task to the
foreground, and then clear it to its root state. This is especially
useful, for example, when launching an activity from the notification
manager.
You have so many ways to achieve your usecase
Possible way1: you can use startActivityForResult method to start the activity from C, D and based on result E you can manage to finish the activities C,D on
onActivityResult()
Possible way 2: If you don't want to keep the Activities on the backstack,
You can finish that activities C, D after they started another
Possible way 3: You can use Intent Flags to manipulate backstack
Let me know if you need further help
For your info
You can use finishAffinity() task in Activity to finish all your previous activities.
it will Finish the activity as well as all activities immediately below it
in the current task that have the same affinity. This is typically
used when an application can be launched on to another task (such as
from an ACTION_VIEW of a content type it understands) and the user
has used the up navigation to switch out of the current task and in
to its own task. In this case, if the user has navigated down into
any other activities of the second application, all of those should
be removed from the original task as part of the task switch.
Note that this finish does not allow you to deliver results
to the previous activity, and an exception will be thrown if you are trying
to do so
you can clear the Activity by calling finish(). override the onBackPressed() and use intent to go to B Activity from E .
I don't understand how to do my use case between the launchmode of activity and the flag of intent.
What i want to do :
A => B => C => B when i back B => C => A
In other word, i want to have a single instance of all activity in the stack and if i recall one of the single instance the activity go to top of stack (with reset or destroy + recreate don't have importance, id o my logic of creation in onresume so), exception for my custom splashscreen (but i resolve this one with noHistory for this activity "splashscreen").
I tried standard mode with flag
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP or with this flag Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT but that don't have the behavior that i want.
So if you can tell me which launchmode and/or flag i should use for made what i want, i would be grateful.
FLAG_ACTIVITY_REORDER_TO_FRONT seems appropriate in your case:
FLAG_ACTIVITY_REORDER_TO_FRONT
If set in an Intent passed to Context.startActivity(), this flag will cause the launched activity to be brought to the front of its task's history stack if it is already running.
For example, consider a task consisting of four activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then B will be brought to the front of the history stack, with this resulting order: A, C, D, B. This flag will be ignored if FLAG_ACTIVITY_CLEAR_TOP is also specified.
If we leave out Activity D in the above description we get:
A, B, C (start B) => A, C, B
Which appears to be what you want.
I need to do the following: I have 5 activities and I call them like this A->B->C->D->E but when activity E finishes, then it should return to activity B keeping A first, like this: A->B. How can I do that? Thanks
You want FLAG_ACTIVITY_CLEAR_TOP:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.
Don't create a new task.
Supposing I have the following activities:
Activity A
Activity B
Activity C
Activity D
A calls B, B calls C and C calls D, so my stack is, from top to bottom, D-C-B-A.
Now I want call from D the activity B in order to obtain the following stack:
B-A
Where B is not the previous instance that was in the initial stack configuration (D-C-B-A) but is a new instance.
What FLAG_ACTIVITY_ I have to use?
I have tried using this :
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
But this give me the old instance of Activity B, on top of the stack.
Take out the flag Intent.FLAG_ACTIVITY_SINGLE_TOP. From the docs:
The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance's onNewIntent().
how can i call an activity from stack instead of launching new instance ?
here is a scenario :
calling activity A with parameters in order to retrieve data
navigate from A to B
navigate from B to C
i want launch A again but not with a new instance , i want get it from the stack so no need to pass parameters and wait to retrieve data.
If I get your point correctly you can simple exit your activity B and C with finish();.
So if you ActivityC finishes and also ActivityB the ActivityA should come to the front, which should be that what you want.
Try to use FLAG_ACTIVITY_REORDER_TO_FRONT. For example:
Intent intent = new Intent(BActivity.this, AActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
From javadocs:
public static final int FLAG_ACTIVITY_REORDER_TO_FRONT
Added in API
level 3
If set in an Intent passed to Context.startActivity(), this flag will
cause the launched activity to be brought to the front of its task's
history stack if it is already running.
For example, consider a task consisting of four activities: A, B, C,
D. If D calls startActivity() with an Intent that resolves to the
component of activity B, then B will be brought to the front of the
history stack, with this resulting order: A, C, D, B. This flag will
be ignored if FLAG_ACTIVITY_CLEAR_TOP is also specified.