54

I have an application with several Activities in Android and I want the user to be able to log-out by pressing a menu button. The problem I have is that

A) Android doesn't let you terminate the application and
B) even when I send the user to the LoginActivity again they can always press back and get right back to the previous activity they were in.

I already tried to launch the Activity with the two following flags:

Intent intent  = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);        
startActivity(intent);

I also tried with each one of them by themselves.

I also tried calling finish() after startActivity(intent) as I read in another StackOverflow question.

JJD
  • 50,076
  • 60
  • 203
  • 339
Totic
  • 1,281
  • 1
  • 10
  • 21

10 Answers10

42

This should be bitwise OR'd or you end up overwriting the earlier flag.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

Like so:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
deweylewie
  • 523
  • 4
  • 5
  • i have try it many time but not get required result. please help me – amity Sep 24 '11 at 08:27
  • 30
    The only way this works is if the activity you are trying to start is already in the activity stack. Android Y U SO WEIRD? – mxcl Mar 08 '12 at 18:16
  • This won't work with API level < 11. Check my [answer](http://stackoverflow.com/a/24352988/636561) for a solution compliant with API level >= 1. – Luca Fagioli Jun 22 '14 at 16:15
  • Okay, so I have a user constantly switching between activities, meaning they may have switched 15 activities in 20 seconds. Could that be a cause of an out of memory error? What should I do to fix it? Thanks! – Ruchir Baronia Jan 05 '16 at 06:00
36

In your login activity, override the back button, so it hides your app instead of finishing the activity:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Also be sure to set android:alwaysRetainTaskState="true" on the root activity, so Android doesn't clear your stack (including the login activity) after 30min of inactivity from user.

Then just call finish() when there is a successful login.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • 8
    Thanks, your code got me in the right path, but this will do the same: @Override public void onBackPressed(){ moveTaskToBack(true); } – Totic Nov 16 '10 at 05:16
  • Okay, so I have a user constantly switching between activities, meaning they may have switched 15 activities in 20 seconds. Could that be a cause of an out of memory error? What should I do to fix it? Thanks! – Ruchir Baronia Jan 05 '16 at 06:00
31

As per Wakka in Removing an activity from the history stack...


Add android:noHistory="true" attribute to your <activity> in the AndroidManifest.xml like this:

<activity android:name=".MyActivity"
    android:noHistory="true">
</activity>
Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
6

If you are using Android API 11 or above, you can use the following code to clear the stack.

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
Pratik
  • 30,639
  • 18
  • 84
  • 159
matangs
  • 441
  • 5
  • 8
  • Okay, so I have a user constantly switching between activities, meaning they may have switched 15 activities in 20 seconds. Could that be a cause of an out of memory error? What should I do to fix it? Thanks! – Ruchir Baronia Jan 05 '16 at 06:01
5

This wont clear your activity back stack.

Even after following all the above answer, when I pressed the back button It showed the last activity for a second before closing the app.

This is what I did:

@Override
public void onBackPressed() { 
    Intent startMain = new Intent(Intent.ACTION_MAIN);
    startMain.addCategory(Intent.CATEGORY_HOME);
    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(startMain);
}

Now my app exits on back press :) without any hassle.

JJD
  • 50,076
  • 60
  • 203
  • 339
amalBit
  • 12,041
  • 6
  • 77
  • 94
  • Please keep in mind that much has changed between SDK versions of Froyo and Cupcake when comparing answers. In other words, something which worked a certain way in 2010 might work differently now. – Brandon Mar 10 '14 at 04:01
  • Yes, you are right. I will kepp that in mind. Thanks. – amalBit Mar 10 '14 at 05:27
  • Okay, so I have a user constantly switching between activities, meaning they may have switched 15 activities in 20 seconds. Could that be a cause of an out of memory error? What should I do to fix it? Thanks! – Ruchir Baronia Jan 05 '16 at 06:01
3

Setting Intent.FLAG_ACTIVITY_CLEAR_TOP has worked for me in a very similar case, where I didn't set the Intent.FLAG_ACTIVITY_NEW_TASK flag. Have you tried without?

Pratik
  • 30,639
  • 18
  • 84
  • 159
Brandon
  • 401
  • 3
  • 8
2

This work for me :)

Intent main = new Intent(this, A_Activity.class);
main.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
    | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(main);

Intent tool = new Intent(this, B_Activity.class);
startActivity(tool);
finish();

Where A is my root activity for example

I have activities A -> B -> C -> D when I call start activity E on stack I have now A -> E

I don't know is it good :) but works.

Gelldur
  • 11,187
  • 7
  • 57
  • 68
  • Okay, so I have a user constantly switching between activities, meaning they may have switched 15 activities in 20 seconds. Could that be a cause of an out of memory error? What should I do to fix it? Thanks!' – Ruchir Baronia Jan 05 '16 at 06:01
  • @RuchirBaronia it shouldn't cause out of memory. Probably something is keeping you activities in memory :) Check: http://blogs.innovationm.com/android-out-of-memory-error-causes-solution-and-best-practices/ – Gelldur Jan 05 '16 at 15:55
1
Intent intent  = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);        
startActivity(intent);

write this and note: LoginActivity must be launched first as Launcher and

if you write any launcher modes the flags are overwritten its purpose, so remove the launchermode and try you will surely get it

Pratik
  • 30,639
  • 18
  • 84
  • 159
Anand Kumar
  • 66
  • 2
  • 8
1

Try this

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(
    Intent.FLAG_ACTIVITY_CLEAR_TOP | 
    Intent.FLAG_ACTIVITY_CLEAR_TASK | 
    Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
JJD
  • 50,076
  • 60
  • 203
  • 339
Raghavendra
  • 2,305
  • 25
  • 30
0

If we use this code to launch Login activity (A):

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

The activity should be in the stack of activities, otherwise this flags will not have any effect.

If we use finish() in the Login activity (A), after launching activity (B) (to avoid going back to A from B), the activity A (Login) will not be in the stack. Exactly the same happens when the login activity has "noHistory" as attribute.

So, the solution for me was a mix of other responses:

This code goes in the activity B, to avoid come back to the login activity:

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

And this code goes in the activity which call the logout function:

public static void logout() {
    Intent intent = new Intent(activity, LoginMain.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
}
Ziem
  • 6,579
  • 8
  • 53
  • 86
Mario Velasco
  • 3,336
  • 3
  • 33
  • 50