Removing an activity from the history stack

AndroidAndroid ActivityActivity Lifecycle

Android Problem Overview


My app shows a signup activity the first time the user runs the app, looks like:

  1. ActivitySplashScreen (welcome to game, sign up for an account?)
  2. ActivitySplashScreenSignUp (great, fill in this info)
  3. ActivityGameMain (main game screen)

so the activities launch each other in exactly that order, when the user clicks through a button on each screen.

When the user goes from activity #2 to #3, is it possible to wipe #1 and #2 off the history stack completely? I'd like it so that if the user is at #3, and hits the back button, they just go to the homescreen, instead of back to the splash screen.

I think I can accomplish this with tasks (ie. start a new task on #3) but wanted to see if there was simpler method,

Thanks

Android Solutions


Solution 1 - Android

You can achieve this by setting the android:noHistory attribute to "true" in the relevant <activity> entries in your AndroidManifest.xml file. For example:

<activity
    android:name=".AnyActivity"
    android:noHistory="true" />

Solution 2 - Android

You can use forwarding to remove the previous activity from the activity stack while launching the next one. There's an example of this in the APIDemos, but basically all you're doing is calling finish() immediately after calling startActivity().

Solution 3 - Android

Yes, have a look at Intent.FLAG_ACTIVITY_NO_HISTORY.

Solution 4 - Android

This is likely not the ideal way to do it. If someone has a better way, I will be looking forward to implementing it. Here's how I accomplished this specific task with pre-version-11 sdk.

in each class you want to go away when it's clear time, you need to do this:

    ... interesting code stuff ...
    Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == R.string.unwind_stack_result_id) {
        this.setResult(R.string.unwind_stack_result_id);
        this.finish();
    }
}

then the one that needs to set off the chain of pops from the stack needs to just call this when you want to initiate it:

NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();

Then the activities aren't on the stack!
Remember folks, that you can start an activity, and then begin cleaning up behind it, execution does not follow a single (the ui) thread.

Solution 5 - Android

One way that works pre API 11 is to start ActivityGameMain first, then in the onCreate of that Activity start your ActivitySplashScreen activity. The ActivityGameMain won't appear as you call startActivity too soon for the splash.

Then you can clear the stack when starting ActivityGameMain by setting these flags on the Intent:

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

You also must add this to ActivitySplashScreen:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

So that pressing back on that activity doesn't go back to your ActivityGameMain.

I assume you don't want the splash screen to be gone back to either, to achieve this I suggest setting it to noHistory in your AndroidManifest.xml. Then put the goBackPressed code in your ActivitySplashScreenSignUp class instead.

However I have found a few ways to break this. Start another app from a notification while ActivitySplashScreenSignUp is shown and the back history is not reset.

The only real way around this is in API 11:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

Solution 6 - Android

I use this way.

Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

Solution 7 - Android

I know I'm late on this (it's been two years since the question was asked) but I accomplished this by intercepting the back button press. Rather than checking for specific activities, I just look at the count and if it's less than 3 it simply sends the app to the back (pausing the app and returning the user to whatever was running before launch). I check for less than three because I only have one intro screen. Also, I check the count because my app allows the user to navigate back to the home screen through the menu, so this allows them to back up through other screens like normal if there are activities other than the intro screen on the stack.

//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
@Override
public void onBackPressed() {
	//Check the activity stack and see if it's more than two deep (initial screen and home screen)
	//If it's more than two deep, then let the app proccess the press
	ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
	List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
	int activityCount = tasks.get(0).numActivities;
	
	if (activityCount < 3)
	{
		moveTaskToBack(true);
	}
	else
	{
		super.onBackPressed();
	}
}

Solution 8 - Android

In the manifest you can add:

android:noHistory="true"

<activity
android:name=".ActivityName"
android:noHistory="true" />

You can also call

finish()

immediately after calling startActivity(..)

Solution 9 - Android

Just set noHistory="true" in Manifest file. It makes activity being removed from the backstack.

Solution 10 - Android

It is crazy that no one has mentioned this elegant solution. This should be the accepted answer.

SplashActivity -> AuthActivity -> DashActivity

if (!sessionManager.isLoggedIn()) {
    Intent intent = new Intent(context, AuthActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    context.startActivity(intent);
    finish();
} else {
   Intent intent = new Intent(context, DashActivity.class);
   context.startActivity(intent);
    finish();
}

The key here is to use intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); for the intermediary Activity. Once that middle link is broken, the DashActivity will the first and last in the stack.

android:noHistory="true" is a bad solution, as it causes problems when relying on the Activity as a callback e.g onActivityResult. This is the recommended solution and should be accepted.

Solution 11 - Android

It's too late but hope it helps. Most of the answers are not pointing into the right direction. There are two simple flags for such thing.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

From Android docs:

> public static final int FLAG_ACTIVITY_CLEAR_TASK > Added in API level 11 > > 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.

Solution 12 - Android

Just call this.finish() before startActivity(intent) like this-

       Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
        this.finish();
        startActivity(intent);

Solution 13 - Android

Removing a activity from a History is done By setting the flag before the activity You Don't want

A->B->C->D

Suppose A,B,C and D are 4 Activities if you want to clear B and C then set flag

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

In the activity A and B

Here is the code bit

Intent intent = new Intent(this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);

Solution 14 - Android

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            super.finishAndRemoveTask();
        }
        else {
            super.finish();
        }

Solution 15 - Android

Try this:

intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)

it is API Level 1, check the link.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarkView Question on Stackoverflow
Solution 1 - AndroidAitor GómezView Answer on Stackoverflow
Solution 2 - AndroidDan LewView Answer on Stackoverflow
Solution 3 - AndroidMatthiasView Answer on Stackoverflow
Solution 4 - AndroidTravisView Answer on Stackoverflow
Solution 5 - AndroidmxclView Answer on Stackoverflow
Solution 6 - AndroidSmiderleView Answer on Stackoverflow
Solution 7 - Androidalphonzo79View Answer on Stackoverflow
Solution 8 - AndroidAnubhavView Answer on Stackoverflow
Solution 9 - AndroidStanislaw BrzezinskiView Answer on Stackoverflow
Solution 10 - AndroidOtieno RowlandView Answer on Stackoverflow
Solution 11 - AndroidNouman GhaffarView Answer on Stackoverflow
Solution 12 - Androiduser8269411View Answer on Stackoverflow
Solution 13 - AndroidrickyView Answer on Stackoverflow
Solution 14 - AndroideagerprinceView Answer on Stackoverflow
Solution 15 - AndroidAlécio CarvalhoView Answer on Stackoverflow