Android: Clear Activity Stack
Asked Answered
F

12

146

I'm having several activities in my application. and flow is very complicated. When I click the Logout application navigates to login Screen and from there user can exit by cancel button (calling system.exit(0) )

when I exit or back button, the system invokes an activity from stack :( how can I clear all the activities in the stack when I reach Login screen? calling finish() is not practical as there are so many activities and some activities should no be closed when they are active such as native camera invoking activity.

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);
Forename answered 16/8, 2011 at 8:16 Comment(2)
check this link ... https://mcmap.net/q/152298/-exit-an-android-app/…Labors
Possible duplicate of Android: Clear the back stackSherwood
F
369

Most of you are wrong. If you want to close existing activity stack regardless of what's in there and create new root, correct set of flags is the following:

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

From the doc:

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.

Football answered 5/5, 2013 at 20:5 Comment(6)
Worked perfectly. Thanks. Strangely didn't give error with minSDK=9.Mindi
Frankly I never used this functionality, resurrect after crash, etc., and rather focused on fixing the issues that caused crash )Football
Same functionality also provides IntentCompat.makeRestartActivityTask from support library.Bolen
Adding only those two flags leaves activity stack track behind (starts on top of the previous one), then added Intent.FLAG_ACTIVITY_CLEAR_TOP which simply restarts the application and then exits totally. I haven't added any flag to activities explicitly tho. What could be the problem?Gomuti
Doesn't send to work with singleInstance launchMode activitiesNeuberger
One of the best beginnings: "Most of you are wrong."Carolann
B
30

When you call startActivity on the last activity you could always use

Intent.FLAG_ACTIVITY_CLEAR_TOP

as a flag on that intent.

Read more about the flag here.

Bouton answered 16/8, 2011 at 8:20 Comment(8)
that also doesn't help. I just brings up an activity dat doesn't ended with finish(); :(Forename
I guess FLAG_ACTIVITY_CLEAR_TOP clears the activities on the top. My problem is activities on the bottom :(Forename
I guess it depends on how the flow actually is. You should read more about it here: developer.android.com/reference/android/content/… and developer.android.com/guide/topics/fundamentals/…Bouton
Could be, try to use the flag more or maybe try to improve your flow. Perhaps as singleTask or something similar.Bouton
Thanks for showing correct resources. the mistake i did was closing the Login activity. I should not close it. When the activity loaded first. so when I call it back using Clear_top flag, login activity clears all the activities on the top. since login is the first entrace activity, it clears all the activities started after. so bingo it worked :)Forename
From the documentation, FLAG_ACTIVITY_CLEAR_TOP clears the stack only if the specific activity "already running in the current task"Koan
@Koan good notice. Whats the solution if activity is not already running!Niven
@Umka you should link in that case. "below" is just now, answers my shift in their ordering.Bouton
L
16

Here is a simple helper method for starting a new activity as the new top activity which works from API level 4 up until the current version 17:

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

call it like this from your current activity:

startNewMainActivity(this, MainActivity.class);
Lawson answered 22/5, 2013 at 14:56 Comment(4)
Couldn't you than always just use intent.addFlags(0x8000); and simplify that?Carleton
As this flag was first introduced in Honeycomb I have no idea what implication it might have on earlier versions. So, this was me being precaucios. But I guess removal of the conditial shouldn't be a problem.Lawson
you want to add that flag when API level is < 11 then you need to do Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB else intent.addFlags(0x8000); will never addedLialiabilities
I am having the user go by many activities one after the other through intents. Do I need to do anything in order to make sure the app doesn't crash with too many activities on the stack? Thanks!Ruddie
C
12

Clear Activity Backstate by below code:

Intent intent = new Intent(Your_Current_Activity.this, Your_Destination_Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Done

Canikin answered 21/6, 2015 at 13:58 Comment(6)
I am having the user go by many activities one after the other through intents. Do I need to do anything in order to make sure the app doesn't crash with too many activities on the stack? Thanks!Ruddie
@RuchirBaronia, If you go A -> B -> C -> D -> E -> F -> G -> H, now H -> I you write my code than I will be Last Activity after then you press Back button app will close because app has no backstate activity, hope this will help you.Canikin
Do I need to do that though? What will happen if I never clean activity stack?Ruddie
@RuchirBaronia, Backpress: H -> G -> F -> E -> D -> C -> B -> ACanikin
But some time it shows white screen while calling new activity. Ho to solve this?Spiritism
Adding Intent.FLAG_ACTIVITY_CLEAR_TOP restarts the application and then exits totally. I haven't added any flag to activities explicitly tho. What could be the problem?Gomuti
C
4
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();
Consolute answered 9/10, 2015 at 8:32 Comment(1)
why you are using both this.finish() and setFlags() also to clear current activity ?Spiritism
C
4

This decision works fine:

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

But new activity launch long and you see white screen some time. If this is critical then use this workaround:

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

How use it:

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

Disadvantage: all activities that must be closed on the stack must extends BaseActivity

Cloudless answered 27/8, 2017 at 13:59 Comment(0)
P
4

Using Kotlin:

You can set the flag directly using setter method. In Kotlin or is the replacement for the Java bitwise or |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

If you plan to use this regularly, create an Intent extension function

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

You can then directly call this function before starting the intent

intent.clearStack()
Pizzicato answered 7/1, 2020 at 20:1 Comment(0)
B
3

In my case, LoginActivity was closed as well. As a result,

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

did not help.

However, setting

Intent.FLAG_ACTIVITY_NEW_TASK

helped me.

Barbiturate answered 21/12, 2012 at 0:3 Comment(1)
I am having the user go by many activities one after the other through intents. Do I need to do anything in order to make sure the app doesn't crash with too many activities on the stack? Thanks!Ruddie
M
3

I noted that you asked for a solution that does not rely on finish(), but I wonder if this may help nonetheless.

I tracked whether an exit flag is raised with a static class variable, which survives the entire app lifespan. In each relevant activity's onResume(), use

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

The ExitHelper class

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

Let's say in mainActivity, a user presses a button to exit - you can set ExitHelper.isExitFlagRaised = true; and then finish(). Thereafter, other relevant activities that are resumed automatically will be finished as well.

Muffle answered 3/2, 2016 at 9:20 Comment(1)
what will happen if I use the code in MainActivity onresume() then come back to mainactivity from 2nd activity onbackpressProclamation
C
3

For Xamarin Developers, you can use:

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
Cortie answered 28/12, 2017 at 7:38 Comment(0)
F
0

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

Furthermost answered 16/8, 2011 at 8:16 Comment(0)
W
0
public void logout(View view) {

    Intent intent = new Intent(Current.this, Target.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(intent);

}

This worked! While searching on why this works I found this "Start the activity in a new task, and clear any existing tasks with the same affinity."

I could only found this Document relating to clearing the back stack or the task. Task with the same affinity is also a bit confusing.

For Android Studio Iguana Tested on android api level 34, android upside down cake(Android 14.0)

Wilhelmina answered 10/4 at 15:31 Comment(2)
How does this differ from this answer. What changes are necessary compared to that answer to make it work and why? What would convince someone to try your answer when there are 11 other (undeleted) answers here with upvotes already? As written, your answer is unlikely to get upvoted unless folks try all the other (upvoted) answers first and fail. Convince them that yours is worth trying first! ;-)Caboodle
If possible, please edit your post to add further details, such as explanations or documentation, so that others can confirm that your answer is correct. You can find more information in How do I write a good answer? - "Brevity is acceptable, but fuller explanations are better." It might be helpful to review some highly upvoted answers as examples to follow. Thanks!Caboodle

© 2022 - 2024 — McMap. All rights reserved.