58

Possible Duplicate:
Quitting an application - is that frowned upon?

I want to offer the user an option to exit the application as I need to delete some sensitive data, which is stored in the SharedPreferences as long as the application needs it.

As soon as the user wants to exit, the password in the SharedPreferences should be wiped and of course all activities of the application should be closed (it makes no sense to run them without the known password - they would crash).

How can I do that?

System.exit(0) and finish() only exit the current activity - useless. I know there is a taskmanager app. How is that one doing it? It's able to kill the whole application...

Community
  • 1
  • 1
Nils
  • 1,705
  • 6
  • 23
  • 32
  • 1
    check this: finishAffinity(); – takluiper Jun 06 '18 at 08:19
  • 1
    Interesting question, but you are trying to do it for the wrong way. The solution to the problem behind the question is different to the answer to the question. The solution to the problem is don't use SharedPreferences - cleaning up is not a good reason to quit the activity. – Gerasimos R Nov 19 '18 at 12:08

6 Answers6

112

When you use the finish() method, it does not close the process completely , it is STILL working in background.

Please use this code in Main Activity (Please don't use in every activities or sub Activities):

@Override
public void onBackPressed() {

    android.os.Process.killProcess(android.os.Process.myPid());
    // This above line close correctly
}
rmanalo
  • 342
  • 3
  • 23
Thirumalvalavan
  • 2,660
  • 1
  • 30
  • 32
  • 1
    WoW, right direction!!! Thank you – Ponmalar Aug 09 '12 at 06:34
  • 16
    This will kill the process, but it won't necessarily kill the task in memory. So when the app is restarted, the activity stack (task) will just get re-created from last time. – IgorGanapolsky Jan 25 '13 at 17:49
  • 5
    Yea, I don't like this solution at all. Killing the process takes away any opportunity you might have had to save data or finish any pending tasks. This is like the most blunt, cave man way of closing your application and should be avoided at all cost. – mtmurdock Jun 03 '14 at 13:00
  • how to kill foreign process? – Criss Mar 30 '15 at 09:19
  • 2
    why application restarts after killing process – Bhargav Thanki Aug 01 '15 at 12:26
  • @Bhargav thanki- can post your code or any sample? – Thirumalvalavan Aug 05 '15 at 07:28
  • I tried this solution but the services created of the app continue running.. – mboy Oct 11 '16 at 08:47
  • Please give more information like service or intent service. And please check your service, Is it foreground service or not? – Thirumalvalavan Oct 13 '16 at 07:13
  • 1
    Fixed a problem I was having when trying to 'finish' after Thread.UncaughtExceptionHandler. I notices ps showed the process still active in the suspended state but after exiting the thread, the app wouldn't restart correctly next time. This worked. – steven smith Jul 22 '18 at 23:34
40

You are correct: calling finish() will only exit the current activity, not the entire application. however, there is a workaround for this:

Every time you start an Activity, start it using startActivityForResult(...). When you want to close the entire app, you can do something like this:

setResult(RESULT_CLOSE_ALL);
finish();

Then define every activity's onActivityResult(...) callback so when an activity returns with the RESULT_CLOSE_ALL value, it also calls finish():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

This will cause a cascade effect closing all activities.

Also, I support CommonsWare in his suggestion: store the password in a variable so that it will be destroyed when the application is closed.

Jason Plank
  • 2,336
  • 5
  • 31
  • 40
mtmurdock
  • 12,756
  • 21
  • 65
  • 108
  • RESULT_CLOSE_ALL cannot be resolved to a variable – hamish Jun 02 '14 at 08:18
  • I googled around, and found a couple of people using zero public final static int RESULT_CLOSE_ALL = 0; – hamish Jun 02 '14 at 08:25
  • it doesn't work. I have an area of the screen that when clicked is supposed to close the app. but I get this compile error. seems you can't use this code on the public class GaugeControl extends View { The method finish() is undefined for the type GaugeControl – hamish Jun 02 '14 at 08:26
  • If your code us not compiling then you have done something wrong. Finish is a method on the activity, not on the view. Also RESULT_CLOSE_ALL is not some magic variable, you have to declare it. If it can't be resolved then you have skipped a step. – mtmurdock Jun 03 '14 at 11:34
  • great solutions @mtmurdock love it :D – gumuruh Jul 11 '14 at 10:05
  • My application still appears in the opened apps menu with this approach, is there anything cleaner? – Ringo Aug 08 '14 at 23:44
  • That's fine. Your app is never fully closed, and that's fine. It shouldn't be. This is how mobile apps are supposed to work. This is the clean approach because it shuts down all active tasks without skipping any cleanup steps. – mtmurdock Aug 10 '14 at 00:13
  • great solution! I was looking for something similar and i just red the code to understand that... it's a great solution! – iGio90 Sep 08 '14 at 23:54
  • 1
    This should be the accepted answer. It is the most correct and the cleanest answer by far, working with android instead of against it, using the tools and apis provided, and not doing heavy-handed process kills. Wish I could +2 to bump it up. – Gerasimos R Nov 19 '18 at 12:06
15

When the user wishes to exit all open activities, they should press a button which loads the first Activity that runs when your app starts, in my case "LoginActivity".

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. LoginActivity is the first activity that is brought up when the user runs the program. Then put this code inside the LoginActivity's onCreate, to signal when it should self destruct when the 'Exit' message is passed.

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

The answer you get to this question from the Android platform is: "Don't make an exit button. Finish activities the user no longer wants, and the Activity manager will clean them up as it sees fit."

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
  • good solution, but isn't it an overhead to start the new Activity... – Amit May 21 '12 at 12:08
  • 5
    Yes, but remember, android tries very hard not to give programmers the ability to create an "exit" button for their apps. So you have to trick the language to let you exit the application, by creeping up on it slowly, making it think you only want to stop a few activities, then sneaking up for the final command, letting the last activity finish. It's kind of like getting past a security guard by distracting him, then running by when he isn't looking. – Eric Leschinski May 21 '12 at 15:50
8

which is stored in the SharesPreferences as long as the application needs it.

Why?

As soon as the user wants to exit, the password in the SharedPreferences should be wiped and of course all activities of the application should be closed (it makes no sense to run them without the known password - they would crash).

Even better: don't put the password in SharedPreferences. Hold onto it in a static data member. The data will naturally go away when all activities in the app are exited (e.g., BACK button) or otherwise destroyed (e.g., kicked out of RAM to make room for other activities sometime after the user pressed HOME).

If you want some sort of proactive "flush password", just set the static data member to null, and have your activities check that member and take appropriate action when it is null.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks. That worked, but as soon as there is a crash in any activity and it will be NULL, even other activities will be still there. Well okay ... I guess that's fine – Nils Jun 25 '10 at 04:21
6

Using onBackPressed() method:

@Override
public void onBackPressed() {    
    android.os.Process.killProcess(android.os.Process.myPid());
}

or use the finish() method, I have something like

//Password Error, I call function
    Quit();             


    protected void Quit() {
        super.finish();
    }

With super.finish() you close the super class's activity.

Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • TNX for this < but ho.w to kill foreign process ? like : "org.mozilla.firefox" "org.mozilla.firefox.App" – Criss Mar 30 '15 at 09:20
3

My understanding of the Android application framework is that this is specifically not permitted. An application is closed automatically when it contains no more current activities. Trying to create a "kill" button is apparently contrary to the intended design of the application system.

To get the sort of effect you want, you could initiate your various activities with startActivityForResult(), and have the exit button send back a result which tells the parent activity to finish(). That activity could then send the same result as part of its onDestroy(), which would cascade back to the main activity and result in no running activities, which should cause the app to close.

tlayton
  • 1,757
  • 1
  • 11
  • 13