Android Activity history tracking and clearing partially - android

Imagine this activity history stack:
A > B > C > D > E
scenario 1:
If the user is on E then on tapping the back button it should navigate to D > C > B > A.
scenario 2:
If the user is on E then on tapping a custom button "Show B", then it should clear E > D > C. Which is similar to Finish().
Like X > Y if we set finish on Y the X will be displayed. Similar If I tape Show B on E then E > D > C should be cleared from the stack.
I need to achieve both scenarios.
(Edited ^^^^ with scenarios)
If the user is on E activity and wants to move B. If B is in history stack can we clear C > D > E so that user can navigate to B without startActivity(B). and A should be in history.
If an activity is available in the stack then it should load from history if not startActivity(B).
If I use FLAG_ACTIVITY_CLEAR_TOP/FLAG_ACTIVITY_NEW_TASK, it will clear full history and start's new activity.
I want to clear partial history.
Will it be possible to achieve? If so, how to do it please?

This is all pretty standard. Don't use any special launch modes. Normally, pressing BACK will just finish the current Activity and drop you back into the previous one.
For this case:
If the user is on E then on tapping a custom button "Show B", then it
should clear E > D > C. Which is similar to Finish().
In E, to go back to the existing instance of B, do this:
Intent intent = new Intent(this, B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
This will finish E, D and C and return to the existing instance of B.
The flag FLAG_ACTIVITY_CLEAR_TOP tells Android to clear all activities between the current Activity and the target Activity. If you don't specify FLAG_ACTIVITY_SINGLE_TOP then the existing instance of the target Activity will also be finished and a new instance will be created. If you do specify FLAG_ACTIVITY_SINGLE_TOP then the existing instance of the target Activity will NOT be finished and a new instance will NOT be created.

You can achieve this using
android:launchMode="singleTask"
in your manifest file. For more refer this documentation https://android.jlelse.eu/android-activity-launch-mode-e0df1aa72242

Related

Android start a new activity before another activity in backstack and clear activities above old activity

I'm stuck with an Activity backstack question. Let's say I have 5 activities in my backstack: like Activity A, Activity B, Activity C, Activity D and Activity E. At some point I want the user to go to another Activity G, when pressed on the back button on Activity E. Activity G needs to be put after Activity B, so I want Activity C and Activity D removed from the backstack (otherwise the user would go to Activity D).
Current situation A --> B --> C --> D --> E
Preferred situation A --> B --> G
Now I understand I can use FLAG_ACTIVITY_CLEAR_TOP when Activity G would have been in the backstack. But the Activity isn't. Also I don't want to use FLAG_ACTIVITY_NEW_TASK because then Activities A and B would also be gone.
Another approach would be to put
android:noHistory="true"
within the manifest for Activities C and D, but this would make the user go back to Activity B every time the user pressed the back button from within Activity C or D.
Who can point me in the right direction?
You can try below
C ----startActivityForResult----------> D ---startActivityForResult--> E
handle onActivityResult with result accordingly to finish Activities, make sure its chained action calls
When you start activity from C->D you put finish();
Intent intent=new Intent(C.this,D.class);
startActivity(intent);
finish();
same way for D->G this way it is possible.

FLAG_ACTIVITY_CLEAR_TOP does not work as expected

I have 4 activities A, B, C, D, E with each declared as android:launchMode="singleInstance" and A being parentActivity of B, and B being parent Activity of C, in manifest.
Now user navigated to E like this: A > B > C > D > E.
And I have a button in E with the following onClickListener
Intent intent = new Intent(E.this, C.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
What I need? (Also according to documentation, if I understood it right, this should happen)
Activities D and E should be cleared from stack
Activity C should be resumed receiving the intent (as singleInstance is set, it will not be created newly)
I want this stack: C | B | A
What's happening?
Activity C is resumed receiving the intent
Activities D and E are NOT cleared from stack. I can click back button again and again to see E, D, B, A.
I get this stack: C | E | D | B | A
PS: My question is very similar to this however, the answers given there does not suit this question. Some answers I found there and elsewhere:
I can't use NEW_TASK flag, as I need to keep A, B in stack alive.
I can't use startActivityForResult() on D and then finish() it which in fact is a hack, as I have other decisive factors in E such as delivering the intent to some other activity depending on user input.
I can't finish() activity D, while delivering intent to E, and then finish() E while hitting C, which would actually solve the problem. But, if back is pressed on E, i want it go back to D and not C.
When I try finish() on E as soon as I do startactivity(intent) after setting flags, it just finishes E, but not D.
Artem Mostyaev's comment solves the puzzle! Use singleTask
So what exactly was the mistake?
When singleInstance is used as launchMode, and when an activity is launched, Android makes sure that it is launched in a new task as if NEW_TASK flag is added, with itself being the only activity inside it.
So when user navigated to E, the stack was never like [ A | B | C | D | E ]
Instead there were five different tasks like [A] [B] [C] [D] [E].
And when I tried E > C with CLEAR_TOP, it indeed searched for C in its task and tried to clear all activities after C. But C was never there in the task where E resides.
So it tried launching a new activity C, but then as I set launchMode to singleInstance, it had no way other than bringing [C] front while leaving other tasks untouched.
So how singleTask worked?
It created the stack like I wanted [ A | B | C | D | E ] and CLEAR_TOP worked as expected. Done!
The problem is in android:launchMode="singleInstance". According to the documentation for singleInstance:
If this activity tries to start a new activity, that new activity will
be launched in a separate task.
So, your activity D is launched as the new task, and that's why it is not deleted.

Understanding Intent.FLAG_ACTIVITY_CLEAR_TOP

As per the image shown above, I have some queries. It is requested to read each step in order :-
Each block is an Android Activity
Arrow represents the Stack Direction - the order in which activities are opened(A is started when the app was first launched)
Here when the User reaches ACTIVITY F and want to open activity Z (We are using Flag_Activity_clear_top) for the same.
After that from ACtivity Z when the user wants to open the Activity D.
****Our Requirement at this step is - When the Activity D is opened and the user do presses the back button - I WANT THAT USER SHOULD BE REDIRECTED BACK TO THE ACTIVITY C, AFTER THAT ACTIVITY B and so on..** **
Currently when we press back from the activity D(after coming from Z), then we are being redirected to the Activity Z.
CLEAR_TOP isn't good, because if you open an activity that way, it will remove the whole stack and that doesn't sound like what you want.
Try this:
When starting activity E (from D), F (from E) and Z (from F), do it with the flag "FLAG_ACTIVITY_NO_HISTORY". This flag will prevent the new activity to appear in the back stack.
Keep in mind that any activity you open this way will not be registered in the back stack. So, if you hit back while (for example) you're in F, it will return to D.
Hope this helps!
->Incase anyone is facing the same issue. Try sending the intent along with the flags 'FLAG_ACTIVITY_CLEAR_TOP' and 'FLAG_ACTIVITY_SINGLE_TOP'.
->Example mentioned in the docs: link
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 receives the sentIntent, resulting in the stack now being: A, B.

Remove Activities from Stack History in Android

So ..
let's Suppose the Following Sequence of Activities
A -> B -> C -> D -> E
if I do The Action1 in E I just want remove E from stack and go Back To D.
on the Other hand, If I do The Action2 in E, I want to remove E and D from stack and return to C
how to do that ?
the above sequence is simple implement of messaging App, so A is The Log in Activity and B is The Profile Activity and C show the Friend Request List and D show the Profile of selected person form C, and in C there are 2 button one for approved and the second for cancel requset, now if click any of them it take him to E where Yes or No to do the Opperation, if No it return to profile of Selected person , of yes it should return to C
Well what you can do is that when you go from A->B call finish(); to end activity A, same for B->C, that is end B. So by the time you reach E, only E will be active. So now when you do Action1, call Activity D, and when you do Action2 call activity C. And this time call finish(); on E. This would do exactly what you want.
Every time when you move from one Activity to another you can add this flag with the intent Intent.FLAG_ACTIVITY_CLEAR_TOP. This will clear your all previous activities so that in Activity E there will be no Activity in Stack.
If it always the last activity who is going to perform this kind of action then you can start that last activity for result. So when D is spawning E, do it using startActivityForResult (Intent intent, int requestCode). And later when you perform actions in E, call finish() for E and before doing that pass a result code to D. Based on that result you can either do nothing (so D will remain as it is) or you can call finish() on D as well.
if by stack u mean recent application then to clear recent application you can add
android:excludeFromRecents="true"
inside your activity tag in manifest.xml
If Action1 do nothing since if a user press the Back button, E will be removed and you are back to D. If Action2, start C with flag Intent.FLAG_ACTIVITY_CLEAR_TOP, the D and E would be cleared from the stack

How to finish multiple activities on a button click?

I am implementing android application which is on web service. I'm creating login Activity A then homepage Activity B and so on.
Suppose there are A, B, C, D and E etc. activities. I'm creating a home button in Activity E and by clicking on that Activity E, D and C should finish and home Activity B should resume.
How can I implement that?
A > B > C > D > E > back button in E
Activity > B.
Take a look at the FLAG_ACTIVITY_CLEAR_TOP flag.
In essence it does the following. If the Activity this Intent is directed to is paused in your current back stack then it will resume it and clear the stack above it destroying all the activities in the stack above it.
UPDATE: In response to Jason Hanley.
Thanks for mentioning it. The documentation of FLAG_ACTIVITY_CLEAR_TOP covers that example. If you don't want Activity B to be recreated but just passed the new Intent then you should define its launch mode as singleTop.
Use onActivityResult method in chain . Start closing with the outermost activity-E when pressed on home , then check for its result and accordingly close activity-D and so on .

Categories

Resources