How do you use Intent.FLAG_ACTIVITY_CLEAR_TOP to clear the Activity Stack?

196,391

Solution 1

@bitestar has the correct solution, but there is one more step:

It was hidden away in the docs, however you must change the launchMode of the Activity to anything other than standard. Otherwise it will be destroyed and recreated instead of being reset to the top.

Solution 2

I have started Activity A->B->C->D. When the back button is pressed on Activity D I want to go to Activity A. Since A is my starting point and therefore already on the stack all the activities in top of A is cleared and you can't go back to any other Activity from A.

This actually works in my code:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent a = new Intent(this,A.class);
        a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(a);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}       

Solution 3

For this, I use FLAG_ACTIVITY_CLEAR_TOP flag for starting Intent
(without FLAG_ACTIVITY_NEW_TASK)

and launchMode = "singleTask" in manifest for launched activity.

Seems like it works as I need - activity does not restart and all other activities are closed.

Solution 4

Though this question already has sufficient answers, I thought somebody would want to know why this flag works in this peculiar manner, This is what I found in Android documentation

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().


So, Either,
1. Change the launchMode of the Activity A to something else from standard (ie. singleTask or something). Then your flag FLAG_ACTIVITY_CLEAR_TOP will not restart your Activity A.

or,

2. Use Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP as your flag. Then it will work the way you desire.

Solution 5

I use three flags to resolve the problem:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK | 
                Intent.FLAG_ACTIVITY_NEW_TASK);
Share:
196,391
piusvelte
Author by

piusvelte

Updated on August 19, 2021

Comments

  • piusvelte
    piusvelte over 2 years

    I've read through several posts about using this, but must be missing something as it's not working for me. My activity A has launchmode="singleTop" in the manifest. It starts activity B, with launchmode="singleInstance". Activity B opens a browser and receives and intent back, which is why it's singleInstance. I'm trying to override the back button so that the user is sent back to the activity A, and can then press Back to leave the activity, rather than back to activity B again.

    // activity B
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)  {
     if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
      && keyCode == KeyEvent.KEYCODE_BACK
      && event.getRepeatCount() == 0) onBackPressed();
     return super.onKeyDown(keyCode, event);
    }
    @Override
    public void onBackPressed() {
     startActivity(new Intent(this, UI.class)
     .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
     return;
    }
    

    After returning from the browser, the stack is... A,B,Browser,B

    I expect this code to change the stack to... A ... so that pressing back once more takes the user back to the Home Screen.

    Instead it seems to change the stack to... A,B,Browser,B,A ...as though those flags aren't there.

    I tried calling finish() in activity B after startActivity, but then the back button takes me back to the browser again!

    What am I missing?

  • piusvelte
    piusvelte over 13 years
    I did read the flag, and it sounded like what I needed. Regardless, removing FLAG_ACTIVITY_NEW_TASK has no effect on the outcome. It's still an endless back button loop... A->B, back to A, back to B, back to A...
  • 100rabh
    100rabh over 13 years
    Are you sure why you are using B as singleInstance ?A A "singleInstance" activity acts as if FLAG_ACTIVITY_NEW_TASK was in the intent.Check developer.android.com/guide/topics/fundamentals.html
  • piusvelte
    piusvelte over 13 years
    B needs to receive the intent called back from the browser. I tried changing the launchmode to singleTask, and that still works, but the back button looping still occurs.
  • 100rabh
    100rabh over 13 years
    i think it didn't worked because you used FLAG_ACTIVITY_NEW_TASK there.Better use only FLAG_ACTIVITY_CLEAR_TOP & avoid using neither singleTask nor singleInstance
  • piusvelte
    piusvelte over 13 years
    I've removed FLAG_ACTIVITY_NEW_TASK, and am using only FLAG_ACTIVITY_CLEAR_TOP. I'm no longer using singleTask or singleInstance. Now the callback from the browser creates a new instance of B, losing the state, so that's broken, and it still loops between A and B when pressing Back. :(
  • Derk-Jan
    Derk-Jan over 10 years
    Actually... Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP will do just that.
  • yonojoy
    yonojoy over 10 years
    I think that should be a working solution, if you add Intent.FLAG_ACTIVITY_SINGLE_TOP to prevent the recreating
  • Darpan
    Darpan over 9 years
    I checked, Solution of Bitster doesn't work. While this solution worked. RootActivity did not restart.
  • Darpan
    Darpan over 9 years
    This solution is closing all the intermediary activities; but also, restarting the RootActivity. You may check @Steel_Fedex's solution below. It does the same, but does not restart RootActivity.
  • Darpan
    Darpan over 9 years
    Check Steel_fedex's solution for its example.
  • Jesper Bischoff-Jensen
    Jesper Bischoff-Jensen over 9 years
    Choose your words more wisely. Bitestar solution actually works!
  • Tash Pemhiwa
    Tash Pemhiwa almost 8 years
    This is the best solution for my case. I actually want the root activity to start up again
  • Jishi Chen
    Jishi Chen over 7 years
    singleTask works for me, so Activity will not recreate, and handle event in onNewIntent.
  • vlasentiy
    vlasentiy about 5 years
    First time see this flag, but it worked for my case, thanks
  • ChangWon Jeong Juicycool
    ChangWon Jeong Juicycool about 4 years
    so where the hell is Steel_fedex's solution?!