420

My application has the following flow screens :

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Now I have a common log out button in each screens

(Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

I want that when user clicks on the log out button(from any screen), all the screens will be finished and a new screen Log in will open .

I have tried nearly all FLAG_ACTIVITY to achieve this. I also go through some answers in stackoverflow, but not being able to solve the problem. My application is on Android 1.6 so not being able to use FLAG_ACTIVITY_CLEAR_TASK

Is there any way to solve the issue ?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Tanmay Mandal
  • 39,873
  • 12
  • 51
  • 48

29 Answers29

602

Use:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

This will clear all the activities on top of home.

Assuming you are finishing the login screen when the user logs in and home is created and afterward all the screens from 1 to 5 on top of that one. The code I posted will return you to home screen finishing all the other activities. You can add an extra in the intent and read that in the home screen activity and finish it also (maybe launch login screen again from there or something).

I am not sure but you can also try going to login with this flag. I don't know how the activities will be ordered in that case. So don't know if it will clear the ones below the screen you are on including the one you are currently on but it's definitely the way to go.

Halo
  • 1,730
  • 1
  • 8
  • 31
DArkO
  • 15,880
  • 12
  • 60
  • 88
  • 1
    User is showing his first screen as home screen,thats the main issue. – Tanmay Mandal Jun 13 '11 at 13:21
  • well as i have it my response you need to get back to the home screen and finish that one. so the process call the intent above from any screen. receive the intent on the Home screen and instantly lauch a intent towards login and finish home after the startActivity method. you can also override the pending animation to null for in and out so that it doesn't show the transition ( i do that because it feels kinda quicker).so that should be working fine for the thing you need. – DArkO Jun 13 '11 at 13:36
  • Clear top will work for clearing everything above the activity you are calling with the intent. so this means since activities are stacking above home they will be cleared. its just a matter of starting the login activity afterwards. i have been using it like that and i had no issues with it. also you need to declare the activity to have a single instance so you dont accidently launch another instance of the home activity (which then would be on top and wont clear things below) – DArkO Jun 13 '11 at 13:40
  • 12
    Rather than declare the activity as `singleInstance`, consider using `FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP` as the flags for the Intent. This will finish intervening activities and start (or bring back to the foreground) the desired activity. – CommonsWare Jun 13 '11 at 14:05
  • Yeah @CommonsWare is right. i didn't think of that. but still as a discussion maybe: why not actually declare the activity singleTop/singleInstance? its the home activity. i don't think there would be a reason at any point to have 2 instances of that one right? – DArkO Jun 13 '11 at 14:30
  • @DArkO: Few apps need a `singleInstance` activity -- that's mostly for home screens. You can declare `singleTop` if you want; I personally prefer to manage that at the `Intent` level. – CommonsWare Jun 13 '11 at 14:38
  • 14
    @ CommonsWare Adding `intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);` to my activity did not help me.It did not finish the intervening activities.When I press back from the Login screen I can see the previous activities.Here is my code `Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);`. – Tanmay Mandal Jun 13 '11 at 14:51
  • @CommonsWare ok that seems reasonable. but from my experience singleTop solves some cases where you forget to add the Single top flag and also when working in a team than its more of a coding convention whether to use the flag or the manifest declaration. nvm lets get back to this question. @Tanmay Mandal you shouldnt launch the login activity because it will launch it on top of the others since it is created from scratch when you call the intent. what i said was to actually launch the home activity and from it launch the Login and finish the home. that will clear the Top activities. – DArkO Jun 13 '11 at 14:58
  • @DArkO I think thats the solution I need to implement.calling the home and then finish it and call the login.let me try it. – Tanmay Mandal Jun 13 '11 at 15:00
  • This is great one, for which I am searching. This code will be always useful for me. Thanks a lot. – Umesh Suryawanshi Oct 30 '12 at 10:25
  • It still keep open current activity, getActivity().finishAffinity() worled in my case. – CoDe Aug 05 '14 at 10:43
  • No it wont keep the current activity alive, in your case this means that your old activity doesn't exist and a new one is opened on top instead of going back down through the stack. – DArkO Aug 05 '14 at 10:48
  • 37
    this code only clear the top activity stack, for clearing all activities intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK); – Ajay Venugopal Apr 01 '16 at 09:38
  • Not sure this is acceptable as it relaunches an activity again iinstead of just removing and finishing all activities – Jono Jun 29 '17 at 14:09
  • For me it wasn't working initially because i was doing 'setFlags' instead of 'addFlags'. – Amit Tumkur Oct 03 '17 at 11:06
342

You may try Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. It will totally clears all previous activity(s) and start new activity.

tbraun89
  • 2,246
  • 3
  • 25
  • 44
Kong Ken
  • 3,859
  • 2
  • 15
  • 14
  • 11
    The proper solution, but only API 11+ – riwnodennyk Jan 13 '14 at 17:16
  • I ended up using this extra flag as it doesn't cause a delay when showing the main activity (it won't restart it so it's much faster). – Maurizio May 25 '14 at 15:35
  • 2
    @riwnodennyk why API 11+? – Muhammad Babar Jun 06 '14 at 06:31
  • @MuhammadBabar cause it looks like FLAG_ACTIVITY_CLEAR_TASK was introduced only in API 11 http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TASK – riwnodennyk Jun 06 '14 at 09:36
  • @riwnodennyk my bad i thought you are talking about `Intent.FLAG_ACTIVITY_NEW_TASK` – Muhammad Babar Jun 06 '14 at 11:30
  • 17
    Use IntentCompat.FLAG_ACTIVITY_CLEAR_TASK for pre 11 versions – Steven Pena Aug 04 '14 at 20:40
  • I will edit this answer for more convenient solution for newbies. – Naveed Ahmad Jun 03 '15 at 19:09
  • Thanks. This is exactly what I needed. Can’t believe it’s not the accepted solution as the current accepted one didn’t work! – Saifur Rahman Mohsin Jun 24 '15 at 19:19
  • intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| IntentCompat.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK); working for me, thanks! – Marcio Granzotto Oct 26 '15 at 16:12
  • @StevenPena i can't get that flag to work for pre-11. is that the only flag you're adding? I'm doing this `intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);` – ono Jan 15 '16 at 22:41
  • 2
    @ono Yes. That should be all you need. Make sure your target activity's launch mode is set as as "singleTask" in the manifest. – Steven Pena Jan 19 '16 at 10:48
  • @StevenPena just not working, even with singleTask. back always takes me to a previous activity – ono Jan 19 '16 at 20:07
  • @ono Not sure then. I'm only using that one flag and that's the only change to the activity I had to make. The only other thing I've set up is that my initial screen has "alwaysRetainTaskState=false" in the manifest. Maybe that'll fix whatever issue you are having. – Steven Pena Jan 19 '16 at 20:25
  • @StevenPena ok i think i got it. the solution is to NOT finish the initial activity. missed that somewhere – ono Jan 19 '16 at 20:38
  • @StevenPena but now hitting back the 2nd activity takes you back to the initial instead of closing the app. the struggles..... – ono Jan 19 '16 at 20:42
  • This should be the accepted answer. All works without finish() or finishAffinity(), just intent flags. – ralphgabb Sep 11 '19 at 08:16
157

Before launching your new Activity, simply add the following code:

finishAffinity();

Or if you want it to work in previous versions of Android:

ActivityCompat.finishAffinity(this);
Henrique
  • 4,921
  • 6
  • 36
  • 61
  • 12
    ActivityCompat.finishAffinity(this); calls activity.finish() for api < 16. So it won't work. – Aamir Abro Nov 17 '14 at 08:33
  • 1
    @Beto Caldas, I have confirmed the source code myself, it will not work for API < 16 as AamirAbro mentioned. It will just finish the activity that you passing on API < 16. – HendraWD Jun 06 '16 at 07:46
  • 2
    This remains the best solution to date for API > 16 as other solutions create a lag when clearing or recreating a task – al kaj Aug 20 '22 at 10:13
39

When the user wishes to exit all open activities, they should press a button which loads the first Activity that runs when your application starts, clear all the other activities, then have the last remaining activity finish. Have the following code run when the user presses the exit button. In my case, LoginActivity is the first activity in my program to run.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

The above code clears all the activities except for LoginActivity. Then put the following code inside the LoginActivity's onCreate(...), to listen for when LoginActivity is recreated and the 'EXIT' signal was passed:

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Why is making an exit button in Android so hard?

Android tries hard to discourage you from having an "exit" button in your application, because they want the user to never care about whether or not the programs they use are running in the background or not.

The Android OS developers want your program to be able to survive an unexpected shutdown and power off of the phone, and when the user restarts the program, they pick up right where they left off. So the user can receive a phone call while they use your application, and open maps which requires your application to be freed for more resources.

When the user resumes your application, they pick up right where they left off with no interruption. This exit button is usurping power from the activity manager, potentially causing problems with the automatically managed android program life cycle.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
37

I guess I am late but there is simple and short answer. There is a finishAffinity() method in Activity that will finish the current activity and all parent activities, but it works only in Android 4.1 or higher.

For API 16+, use

finishAffinity();

For below 16, use

ActivityCompat.finishAffinity(YourActivity.this);

Hope it helps!

AkshayT
  • 2,901
  • 2
  • 28
  • 32
32
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

This Will work for all Android versions. Where IntentCompat the class added in Android Support library.

Gem
  • 1,516
  • 16
  • 21
30

Use the following for activity

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

remove CLEAR_TASK flag for fragment use.

I hope this may use for some people.

Aristo Michael
  • 2,166
  • 3
  • 35
  • 43
24

On a side note, good to know
This answer works (https://stackoverflow.com/a/13468685/7034327)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();

whereas this doesn't work

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() replaces any previous flags and doesn't append any new flags while .addFlags() does.

So this will also work

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Community
  • 1
  • 1
John
  • 465
  • 5
  • 15
22

From developer.android.com:

public void finishAffinity ()

Added in API level 16

Finish this activity as well as all activities immediately below it in the current task that have the same affinity. This is typically used when an application can be launched on to another task (such as from an ACTION_VIEW of a content type it understands) and the user has used the up navigation to switch out of the current task and in to its own task. In this case, if the user has navigated down into any other activities of the second application, all of those should be removed from the original task as part of the task switch.

Note that this finish does not allow you to deliver results to the previous activity, and an exception will be thrown if you are trying to do so.

Kos
  • 70,399
  • 25
  • 169
  • 233
gmrl
  • 221
  • 2
  • 2
16

If your application has minimum sdk version 16 then you can use finishAffinity()

Finish this activity as well as all activities immediately below it in the current task that have the same affinity.

This is work for me In Top Payment screen remove all back-stack activits,

@Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29

Jaydeep purohit
  • 1,536
  • 17
  • 20
11

In my case I use finishAffinity() function in last activity like:

finishAffinity()
startHomeActivity()

Hope it'll be useful.

Djek-Grif
  • 1,391
  • 18
  • 18
10

For logout button on last screen of app, use this code on logout button listener to finish all open previous activities, and your problem is solved.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
Amrit
  • 339
  • 1
  • 3
  • 10
10

A solution I implemented for this (I think I found it on Stack Overflow somewhere, but I don't remember, so thanks to whoever did that in the first place):

From any of your activities do this:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Then in your LoginActivity, overwrite onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andy
  • 6,869
  • 2
  • 31
  • 24
  • 3
    That's usually a very bad idea, tho it may work, it introduces a point of contact that may break in the future and it will be hard to debug. I'm telling you from experience :) – Martin Marconcini Mar 08 '13 at 22:30
8

i have same problem you can use IntentCompat , like this :

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

this code work for me .

Android api 17

Adnan Abdollah Zaki
  • 4,328
  • 6
  • 52
  • 58
8
    Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();
Prashant Kumar
  • 419
  • 1
  • 5
  • 15
  • 6
    why **FLAG_ACTIVITY_CLEAR_TASK** twice? – Choletski Oct 02 '15 at 15:48
  • 1
    From what I understand, .setFlags replaces the previous flags and does not append any flags. .addFlags is what you wanted to use I presume? Cause all the code above i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); gets wiped out – iOSAndroidWindowsMobileAppsDev Mar 14 '16 at 14:44
  • addFlags Works for me – Jamil Dec 13 '16 at 08:08
  • 1
    `setFlags` will replace all previous, so last `setFlags` is only valid, previous are replaced. So you don't need to call `i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);` – mtrakal May 11 '18 at 09:32
8

instead of using finish() just use finishAffinity();

Hitesh Kushwah
  • 1,351
  • 13
  • 23
6

for API >= 15 to API 23 simple solution.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);
Kamal Bunkar
  • 1,354
  • 1
  • 16
  • 20
6

Log in->Home->screen 1->screen 2->screen 3->screen 4->screen 5

on screen 4 (or any other) ->

StartActivity(Log in)
with
FLAG_ACTIVITY_CLEAR_TOP
Mubeen Ali
  • 2,150
  • 2
  • 18
  • 26
Plamen Nikolov
  • 4,177
  • 3
  • 23
  • 24
  • 2
    When I pressing back button all the previous activities are show in the order they were .those activities need to be closed, when the logout button clicked there will be only one activity in the stack and that will be the login activity.And there is no login screen.User starts from home screen. – Tanmay Mandal Jun 13 '11 at 13:19
5

If you are using startActivityForResult() in your previous activities, just override OnActivityResult() and call the finish(); method inside it in all activities.. This will do the job...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ngesh
  • 13,398
  • 4
  • 44
  • 60
3

I guess I am late but there is simple and short answer. There is a finishAffinity() method in Activity that will finish the current activity and all parent activities, but it works only in Android 4.1 or higher.

For API 16+, use

finishAffinity();

For below 16, use

ActivityCompat.finishAffinity(YourActivity.this);

Hope it helps!

shareedit answered May 27 '18 at 8:03

Akshay Taru

Samuel Quiroz
  • 191
  • 2
  • 5
3

When user click on the logout button then write the following code:

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

And also when after login if you call new activity do not use finish();

nikki
  • 3,248
  • 3
  • 24
  • 29
2

If you log in the user in screen 1 and from there you go to the other screens, use

Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Gabriel Negut
  • 13,860
  • 4
  • 38
  • 45
  • When I pressing back button all the previous activities are show in the order they were .those activities need to be closed, when the logout button clicked there will be only one activity in the stack and that will be the login activity. – Tanmay Mandal Jun 13 '11 at 13:19
  • If you want this behavior, you have to override `onKeyDown` and `onBackPressed` (or `onKeyDown`, if you want to support Android versions < 2.0) in each one of your activities (except the login one), and `startActivity(login)` there as shown above. – Gabriel Negut Jun 13 '11 at 13:26
  • I have a button which will take me to the login screen finishing all activities in the stack.Is it possible? – Tanmay Mandal Jun 13 '11 at 13:31
2

Simply, when you go from the login screen, not when finishing the login screen.

And then in all forward activities, use this for logout:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

It works perfectly.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Asad Rao
  • 3,190
  • 1
  • 22
  • 26
1

I found this way, it'll clear all history and exit

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);
ItamarG3
  • 4,092
  • 6
  • 31
  • 44
Pirooz Jenabi
  • 440
  • 5
  • 7
0

I found this solution to work on every device despite API level (even for < 11)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);
priyankvex
  • 5,760
  • 5
  • 28
  • 44
0

Best way to close all the previous activities and clear the memory

finishAffinity()
System.exit(0);
Shivam Tripathi
  • 640
  • 8
  • 7
0

I have tried the flags on my end and still haven't worked. I have an application with a very similar design and I have a possible solution in terms of logic. I have built my Login and Logout using shared preferences.

If I logout, data in my shared preferences is destroyed/deleted.

From any of my activities such as Home.java I check whether shared preferences has data and in this case it won't because I destroyed it when I logged out from one of the screens. Therefore logic destroys/finishes that activity and takes me back to the Login activity. You can replicate this logic in all your other activities.

However remember to perform this check inside onPostResume() because this is what is called when you go back to Home.java

Code Sample Below:

@Override
protected void onPostResume() {
    SharedPreferences pref = this.getSharedPreferences("user_details", Context.MODE_PRIVATE);
    if (pref.getAll().isEmpty()){
        //Shared Preferences has no data.
        //The data has been deleted
        Intent intent = new Intent(getApplicationContext(), Login.class);
        startActivity(intent);
        finish();
        //Finish destroys that activity which in our case is the Home.java
    }


    super.onPostResume();
}
MosesK
  • 359
  • 3
  • 7
0

If you know the activity you want to finish then, use broadcast receiver. this solution describe how to do it.

  • You might want to give more details, while leaving a reference is good, link only answers are discouraged – mozway Apr 14 '23 at 11:30
  • Assuming that Activity A wants to close activity B, then setup a broadcast receiver in Activity B, and the action will be finish();. when calling from the activity A then if activity B is working it will be killed. otherwise nothing will happen – صلي علي محمد - Atef Farouk Apr 22 '23 at 00:33
-1

In Kotlin this way:

in Another Activity (with some classes), under Imports

var activity:Activity?=null
    get() = field
    set(value) {
        field = value
    }

Then, under onCreate

activity=this

in MainActivity now:

activity?.finish()
Mori
  • 2,653
  • 18
  • 24