How to change the activity history - android

There are six activities A,B,C,D,E and F. Each of them have been opened in the following order: A,B,C,D,E,F. When I now go from activity F to activity B, I would like to have a subsequent press on the back button open activity A. How can this outcome be achieved?

You can achieve this with Intent flags.
When you start Activity B from Activity F you use a flag in your intent.
Intent i = new Intent(context, B.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Intent.FLAG_ACTIVITY_CLEAR_TOP will cause all of the intermediate activities to be finished (C, D and F), and Intent.FLAG_ACTIVITY_SINGLE_TOP will make sure that you return to the same instance of Activity B.
If you want for activity B to be finished and a new instance to be created, remove Intent.FLAG_ACTIVITY_SINGLE_TOP
Also you can change activity B launchMode instead of using Intent.FLAG_ACTIVITY_SINGLE_TOP
Here are some more info on the matter

Related

Go back and forward after onbackpressed clicked

I have 2 activities (MainActivity,SecondActivity)
I am starting SecondActivity from MainActivity now the situation is when I click onbackpress it's return to MainActivity without finishing the second activity
How I can go back to the second activity without reinitializing the activity again?
I created foreground service to display a notification and added the flag start UpdateCurrent to the pending intent but this cause that Oncreate recalled
what is the solution for this ?
If my understanding of your issue is correct, you need to try this:
Intent.FLAG_ACTIVITY_CLEAR_TOP
Intent.FLAG_ACTIVITY_SINGLE_TOP
And this:
Intent int = new Intent(SecondActivity.this, MainActivity.class);
int.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(int);

How to finish Activity in flow, Flow Control

Now I have HomeActivity -> Activity A -> Activity B -> Activity C
After I finish Activity C I expect to see HomeActivity. How can I handle this flow with Intent Flags or any other suggestions?
edit
But Activity A and Activity B should be removed from the stack when Activity C appear.
Activity A B and C this a workflow, So A can go to B and B can go back to A to edit something, After I Submit in B then A and B should be gone and show C as a confirmation
Using launch modes you can achieve this.
use Single Task for the Activity C in manifest file
<activity android:name=".ActivityC"
android:launchMode="singleTask">
Use this code
Intent intent = new Intent(ActivityC.this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish(); // call this to finish the current activity
You should use
setFlags(...)
finish();
If set in an Intent passed to Context.startActivity(), this flag will
cause any existing task that would be associated with the activity to
be cleared before the activity is started. That is, the activity
becomes the new root of an otherwise empty task, and any old
activities are finished. This can only be used in conjunction with
FLAG_ACTIVITY_NEW_TASK.
Code Structure
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
You should kill the activity before starting the next one.
Intent intent = new Intent(ActivityC.this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();

Is there any difference among Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP

I was wondering, what is the difference between the 2 code?
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
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.
FLAG_ACTIVITY_SINGLE_TOP
If set, the activity will not be launched if it is already running at
the top of the history stack.
My understanding is
FLAG_ACTIVITY_CLEAR_TOP - Clear all activities on the top, and prevent more than 1 instance of same Activity within a same task stack.
FLAG_ACTIVITY_SINGLE_TOP - Prevent more than 1 instance of same Activity within a same task stack.
If my understanding is correct, isn't Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP seems redundant?
Can we just write Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP?
FLAG_ACTIVITY_CLEAR_TOP will create a new Activity and close the others on top.
FLAG_ACTIVITY_SINGLE_TOP will just open/re-open that activity, depending if that was already launched.
The new intent will be received at onNewIntent method, in both cases but the first will destroy other activities. We'll need to imagine that there is a stack.
That stack is formed by the order you've started the activities. Think in that scenario. Start Activity A, then start Activity B and then Activity C
The stack would be like that:
_ Activity C
_ Activity B
_ Activity A
Then if you start Activity A whith FLAG_ACTIVITY_CLEAR_TOP, all activities on top of Activity A will be closed, and the intent will be delivered onNewIntent.
It depends on what you have in other parts of your code.
If the only place where you call startactivity is the one you posted, yes the Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP is redundant.
But if you have the same activity launched from another piece of code, this may be not redundant. It all depends on what you have on the activity stack in this moment.

Why does FLAG_ACTIVITY_CLEAR_TOP not work?

As the title says, Why intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) or intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) won't work?
I have 3 Activities let us say A, B and C.
When I am trying to launch Activity A from C with code:
Intent i = new Intent(this, A.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
It simply starts Activity A but doesn't clear the top.! -_-
I have also tried using setFlags().
I read different questions on SO about this problem, but I couldn't find the right answer. >_<
Somebody please help!
Edit
Code for onBackPressed() in activity 'A' as requested by #codeMagic.
#Override
public void onBackPressed(){
if(wvLogin.canGoBack())
wvLogin.goBack();
else
super.onBackPressed();
}
From the documentation for 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.
As you added in your comment, the activity A has been finished before calling B, so this situation doesn't apply. A new instance of activity A will be launched instead.
As I see it, you have two options here:
1) Use the Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK flags. This will start activity A as the root of the stack. It works, but any other activities in the stack will be lost. Assuming A was the first activity (or at least, that you are not interested in any previous activities in the task stack) then it doesn't matter. Note: CLEAR_TASK requires API Level 11.
2) Another possible solution (in case the previous assumption is not true) would be to not use intent flags at all:
B starts C with startActivityForResult().
Instead of calling A, C finishes, having set a result for B indicating that A must be launched.
In B.afterActivityResult(), finish B and launch A.
You are missing the Intent.FLAG_ACTIVITY_SINGLE_TOP flag
Try this:
Intent i = new Intent(this, A.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
You used a diferrent intent: use the one you initialized:
Intent i = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); \\WRONG;;
startActivity(i);
solution:
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); \\RIGHT;;
You could either put a noHistory true to the Activity A in the manifest
android:noHistory=true

How to navigate to a particular activity?

I am having 3 activities. From the third activity, I need to come back to the 1st activity when a GUI button is clicked. I know I can click the "physical" back button 2 times to make this but that is not an option.
So, is there any way I can display the 1st activity, without creating a new instance? I can pass the 1st activity's instance to the third activity, no issue with that.
Use the FLAG_ACTIVITY_CLEAR_TOP in your intent.
From the documentation:
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.
To use:
Intent intent = new Intent(getBaseContext(), FirstActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Intent intent = new Intent(src_ctxt, dest.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
src_ctxt.startActivity(intent);
This should do it
I think you need to make your activity B singleInstance that if it's already create you don't want to create again, that is launch mode of the activity can be defined in manifest android:launchMode that defines how the activity will be instanciated.
in your case use android:launchMode="singleInstance"
or
You can use flag Intent.FLAG_ACTIVITY_NEW_TASK. If the activity is already running it will bring that to front instead of creating new activity.

Categories

Resources