Как выйти из приложения Android программно


322

Я нашел некоторые коды для выхода из приложения Android программно. Вызов любого из следующего кода в onDestroy () полностью закроет приложение?

  1. System.runFinalizersOnExit(true)
    (ИЛИ)
  2. android.os.Process.killProcess(android.os.Process.myPid());

Я не хочу запускать приложение в фоновом режиме после нажатия кнопки «Выйти». Просьба предложить мне использовать любой из этих кодов для выхода из приложения? Если да, то какой код я могу использовать? Это хороший способ выйти из приложения в Android?


Здесь уже так много постов. stackoverflow.com/search?q=how+to+exit+an+android+app
Mudassir

2
Возможный дубликат выхода из приложения - это осуждается?
CommonsWare

используйте 'System.exit (0);' когда вы действительно хотите выйти из приложения. Я сделал это на неисправимой ошибке после показа пользователю сообщения. Если вам нужно, вы даже можете автоматически перезапустить приложение с помощью AlarmManager. Смотрите: blog.janjonas.net/2010-12-20/…
Кто-то где-то

Ответы:


398

Начиная с API 16, вы можете использовать метод finishAffinity, который, кажется, довольно близок к закрытию всех связанных действий по его имени и описанию Javadoc:

this.finishAffinity();

Завершите это действие, а также все действия непосредственно под ним в текущей задаче, которые имеют ту же привязку. Это обычно используется, когда приложение может быть запущено для другой задачи (например, из ACTION_VIEW типа контента, который он понимает), и пользователь использовал навигацию вверх для переключения из текущей задачи в свою собственную. В этом случае, если пользователь перешел к другим действиям второго приложения, все они должны быть удалены из исходной задачи как часть переключения задачи.

Обратите внимание, что это завершение не позволяет вам доставлять результаты к предыдущему действию, и будет выдано исключение, если вы попытаетесь это сделать.


Начиная с API 21 вы можете использовать очень похожую команду

finishAndRemoveTask();

Завершает все действия в этой задаче и удаляет ее из списка недавних задач.


28
Определенно это правильный ответ! Это не хорошее решение, чтобы закончить использование приложения System.exit(0);. Спасибо за ваш ответ! Наконец-то я нашел достойное решение.
Антонио

4
Знаете ли вы, есть ли другое решение по API 14? Спасибо
сценарий Китти

2
Вы можете завершить () каждое действие по отдельности, либо закрыв приложение, либо в жизненном цикле действия.
Сиви

3
ПРЕДУПРЕЖДЕНИЕ! this.finishAffinity () закрывает приложение, удаляя его из памяти, поэтому вы не будете получать push-сообщения и так далее.
Tincho825

7
Это решение работает в 99% случаев. Однако это не разрушит процесс, поэтому, например, Dagger не будет очищен. В тех редких случаях, когда требуется убить процесс, System.exit(0)это единственное решение, которое сработало для меня.
Славян

155
getActivity().finish();
System.exit(0);

это лучший способ выйти из приложения. !!!

Лучшее решение для меня.


да, отлично работает! Нужно позвонить в MainActivity, чтобы заставить его работать!
mz87

Идеальное решение. Нет необходимости прерывать процесс, так как Android лучше знает управление памятью. Однако это обеспечивает решение для завершения действия, а также для выхода из приложения для удобства пользователя.
IAmTheSquidward

Идеальное решение на самом деле. Исправлено много проблем. Спасибо.
superuserdo

26
Я не думаю, что это хорошее решение. Вы не должны заканчивать свою программу, используя System.exit(0);. Правильное решение было опубликовано @sivi (его ответ выше)
Антонио

13
это не решение, оно не работает, если у вас есть стек действий
user3290180

46

finishAffinity();

System.exit(0);

Если вы будете использовать только finishAffinity();без System.exit(0);приложения, оно будет закрыто, но выделенная память будет по-прежнему использоваться вашим телефоном, поэтому ... если вы хотите, чтобы приложение было чистым и действительно вышло, используйте их оба.

Это самый простой метод, который работает где угодно, выйдите из приложения по-настоящему, у вас может быть много открытых действий, и все будет без проблем.

пример по нажатию кнопки

public void exitAppCLICK (View view) {

    finishAffinity();
    System.exit(0);

}

или если вы хотите что-то приятное, например, с диалоговым окном предупреждения с 3 кнопками ДА НЕТ и ОТМЕНА

// alertdialog for exit the app
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

// set the title of the Alert Dialog
alertDialogBuilder.setTitle("your title");

// set dialog message
alertDialogBuilder
        .setMessage("your message")
        .setCancelable(false)
        .setPositiveButton("YES"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // what to do if YES is tapped
                        finishAffinity();
                        System.exit(0);
                    }
                })

        .setNeutralButton("CANCEL"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // code to do on CANCEL tapped
                        dialog.cancel();
                    }
                })

        .setNegativeButton("NO"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // code to do on NO tapped
                        dialog.cancel();
                    }
                });

AlertDialog alertDialog = alertDialogBuilder.create();

alertDialog.show();

3
это правильный ответ, который я искал. спасибо
коряги

если бы я использовал FCM или фоновые задачи в своем приложении, у меня не было бы проблем?
roghayeh hosseini

Это было то, что мне нужно было стереть приложение из памяти
A1m

Пожалуйста, не используйте. System.exit(0);Вы не должны освобождать эту память, система сделает это за вас, если потребуется. Это предполагаемое поведение.
crgarridos

30

Пожалуйста, подумайте над тем, нужно ли вам убить приложение: почему бы не позволить ОС выяснить, где и когда освободить ресурсы?

В противном случае, если вы абсолютно уверены, используйте

finish();

Как реакция на комментарий @dave Appleton: во-первых, прочитайте большой комбо-вопрос @gabriel, опубликованный: « Не одобряется ли выход из приложения?

Теперь, предполагая, что у нас это есть, вопрос здесь по-прежнему имеет ответ: код, который вам нужен, если вы что-то делаете с выходом - это finish(). Очевидно, что вы можете иметь более одного вида деятельности и т. Д., Но это не главное. Позволяет управлять некоторыми из вариантов использования

  1. Вы хотите, чтобы пользователь прекратил все из-за использования памяти и «не работал в фоновом режиме?» Сомнительно. Позвольте пользователю остановить определенные действия в фоновом режиме, но позвольте ОС уничтожить все ненужные ресурсы.
  2. Вы хотите, чтобы пользователь не переходил к предыдущей активности вашего приложения? Ну, или настройте его так, чтобы он не работал, или вам нужна дополнительная опция. Если большую часть времени работает задняя часть = предыдущая активность, не будет ли пользователь просто нажать домой, если он / она хочет сделать что-то еще?
  3. Если вам нужен какой-то сброс, вы можете выяснить, было ли / как / и т.д. ваше приложение завершено, и если ваша активность снова сфокусировалась, вы можете принять меры, показав новый экран вместо того, чтобы перезапустить, где вы были.

Так что, в конце концов, конечно, finish()не убивает все, но это все еще инструмент, который вам нужен, я думаю. Если есть вариант «убить все действия», я его еще не нашел.


30
Звонок finish()не убьет приложение. finish()используется постоянно: Call this when your activity is done and should be closed.это тот же эффект, что и нажатие кнопки «назад».
Таннер Перриен

Готово убьет активность. чем это отличается от убийства приложения?
Нанн

Нет ничего плохого в том, чтобы «убить» или «убить» Activity(а не Application). Например, вы можете начать новое действие, чтобы показать пользователю некоторую информацию. После тайм-аута или нажатия «ОК» вы можете позвонить, finish()чтобы вернуться к операции вызова.
Таннер Перриен

42
Большинство приложений Android имеют более одного вида деятельности.
CommonsWare

4
@Nanne - экран блокировки является примером того, когда вы хотите остановить все действия. Предположим, вы вошли в банковское приложение. Через определенный промежуток времени без взаимодействия с пользователем запускается экран блокировки. Вы захотите остановить все действия, если кто-то нажмет кнопку «Назад» на экране блокировки!
Джабари

19

Я думаю, что приложение должно быть убито в некоторых случаях. Например, есть приложение, которое можно использовать только после входа в систему. У входа в систему есть две кнопки: «Войти» и «Отмена». Когда вы нажимаете кнопку «Отмена», это определенно означает «Завершить приложение». Никто не хочет приложение живым в фоновом режиме. Поэтому я согласен, что в некоторых случаях необходимо закрыть приложение.


2
Я полностью согласен с этим вариантом использования. Также обратите внимание на мое безопасное приложение, которое должно быть доступно в определенном месте и должно быть лучше закрыто, если пользователь не находится в этом месте. Что мне делать?
Sydwell

18

Создайте ExitActivityи объявите это в декларации. И позвоните ExitActivity.exit(context)для выхода из приложения.

public class ExitActivity extends AppCompatActivity {

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

    public static void exit(Context context) {
        Intent intent = new Intent(context, ExitActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        context.startActivity(intent);
    }

}

Это самый популярный ответ, но это взлом. Вызов функции end в onCreate будет выглядеть сбой на большинстве, если не на всех устройствах.
DoruChidean

Хм это взломать, но не глюк. Сначала вызовите метод exit (), он идет поверх всех действий с четким верхом и задачами, а затем завершается сам. здесь вы выходите.
Вивек

1
Не забудьте объявить этот класс в своем манифесте. +1 для умного взлома, хотя.
Taslim Oseni

Это сработало! проголосовал
TuanDPH

17

В Android нет выхода из приложения , SampleActivity.this.finish (); завершит текущую деятельность.

При переходе от одного занятия к другому продолжайте заканчивать предыдущее

Intent homeintent = new Intent(SampleActivity.this,SecondActivity.class);
startActivity(homeintent);
SampleActivity.this.finish();

13

Прежде всего, этот подход требует минимального Api 16.

Я разделю это решение на 3 части, чтобы решить эту проблему более широко.

1. Если вы хотите выйти из приложения в Activity, используйте этот фрагмент кода:

if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
    finishAffinity();
} else if(Build.VERSION.SDK_INT>=21){
    finishAndRemoveTask();
}

2. Если вы хотите , чтобы выйти из приложения в , не активность класса , который имеет доступ к деятельности , то используйте этот код:

if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
    getActivity().finishAffinity();
} else if(Build.VERSION.SDK_INT>=21){
    getActivity().finishAndRemoveTask();
}

3. Если вы хотите выйти из приложения в классе, отличном от Activity, и не можете получить доступ к Activity, например Service, я рекомендую вам использовать BroadcastReceiver. Вы можете добавить этот подход ко всем своим действиям в вашем проекте.

Создайте переменные экземпляра LocalBroadcastManager и BroadcastReceiver. Вы можете заменить getPackageName () + ". Closeapp", если хотите.

LocalBroadcastManager mLocalBroadcastManager;
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(getPackageName()+".closeapp")){
            if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
                finishAffinity();
            } else if(Build.VERSION.SDK_INT>=21){
                finishAndRemoveTask();
            }
        }
    }
};

Добавьте это к методу onCreate () Activity.

mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(getPackageName()+".closeapp");
mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, mIntentFilter);

Также не забудьте вызвать незарегистрированный получатель в методе Activity из onDestroy ().

mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);

Для выхода из приложения вы должны отправить широковещательную рассылку, используя LocalBroadcastManager, который я использую в своем классе PlayService, который расширяет Service.

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(PlayService.this);
localBroadcastManager.sendBroadcast(new Intent(getPackageName() + ".closeapp"));

10

Вы можете использовать finishAndRemoveTask ()из API 21

public void finishAndRemoveTask ()

Завершает все действия в этой задаче и удаляет ее из списка недавних задач.


8

Это зависит от того, как быстро вы хотите закрыть приложение.

Безопасный способ закрыть ваше приложение - finishAffinity ();

После закрытия всех процессов приложение закрывается. Это может занять некоторое время. Если вы закроете свое приложение таким образом и через короткое время перезапустите его, возможно, ваше новое приложение будет запущено в том же процессе. Со всеми незавершенными процессами и одиночными объектами старого приложения.

Если вы хотите быть уверены, что ваше приложение полностью закрыто, используйте System.exit (0);

Это немедленно закроет ваше приложение. Но возможно, что вы повредите файлы, которые открыты в вашем приложении, или редактирование общих настроек не завершится. Так что используйте это осторожно.

Если вы используете сторожевой таймер в сочетании с долгосрочным заданием, вы можете увидеть влияние различных методов.

new ANRWatchDog(2000).setANRListener(new ANRWatchDog.ANRListener() {
    public void onAppNotResponding(ANRError error) {
        MainActivity.this.finishAffinity();
        System.exit(0);
    }
}).start();
for(int i = 0; i < 10; ++i){
    --i;
}

Это убивает ваше приложение через 2 секунды без отображения диалога ANR или чего-то в этом роде. Если вы удалите System.exit (0) , запустите этот код и перезапустите приложение после его закрытия, вы увидите странное поведение, потому что бесконечный цикл все еще работает.


8

Вам лучше использовать, finish()если вы находитесь в Activity, или getActivity().finish()если вы в Fragment.

Если вы хотите полностью выйти из приложения, используйте:

getActivity().finish();
System.exit(0);

6

Простой и простой способ выйти из приложения

Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);

Это просто приносит домашний экран или фактически убивает приложение?
rpattabi

6

Мы хотим, чтобы код был надежным и простым. Это решение работает на старых устройствах и более новых устройствах.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        getActivity().finishAffinity();
    } else{
        getActivity().finish();
        System.exit( 0 );
    }



5

Аналогично @MobileMateo, но в Котлине

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    this.finishAffinity()
} else{
    this.finish()
    System.exit(0)
}

4

Я не уверен, если это осуждается или нет, но это то, как я это делаю ...

Шаг 1 - У меня обычно есть класс, который содержит методы и переменные, к которым я хочу получить глобальный доступ. В этом примере я назову это классом «App». Создайте статическую переменную Activity внутри класса для каждого действия, которое есть в вашем приложении. Затем создайте статический метод с именем «close», который будет запускать finish()метод для каждой из этих переменных Activity, если они НЕ равны NULL . Если у вас есть основное / родительское действие, закройте его последним:

public class App
{
    ////////////////////////////////////////////////////////////////
    // INSTANTIATED ACTIVITY VARIABLES
    ////////////////////////////////////////////////////////////////

        public static Activity activity1;
        public static Activity activity2;
        public static Activity activity3;

    ////////////////////////////////////////////////////////////////
    // CLOSE APP METHOD
    ////////////////////////////////////////////////////////////////

        public static void close()
        {
            if (App.activity3 != null) {App.activity3.finish();}
            if (App.activity2 != null) {App.activity2.finish();}
            if (App.activity1 != null) {App.activity1.finish();}
        }
}

Шаг 2 - в каждом из ваших действий, переопределение onStart()и onDestroy()методы. В onStart(), установите статическую переменную в вашем классе приложения равной " this". В onDestroy(), установите его равным null. Например, в классе «Activity1»:

@Override
public void onStart()
{
    // RUN SUPER | REGISTER ACTIVITY AS INSTANTIATED IN APP CLASS

        super.onStart();
        App.activity1 = this;
}

@Override
public void onDestroy()
{
    // RUN SUPER | REGISTER ACTIVITY AS NULL IN APP CLASS

        super.onDestroy();
        App.activity1 = null;
}

Шаг 3 - Если вы хотите закрыть свое приложение, просто позвоните App.close()из любой точки мира. Все созданные экземпляры будут закрыты! Так как вы только закрываете действия, а не убиваете само приложение (как в ваших примерах), Android может взять на себя эту задачу и выполнить любую необходимую очистку.

Опять же, я не знаю, будет ли это осуждено по любой причине. Если это так, я хотел бы прочитать комментарии о том, почему это так и как это можно улучшить!


Интересно, мне тоже было бы интересно, что другие опытные разработчики Android подумали об этом.
Руди Кершоу

4
Сохраняя ссылку на свою деятельность, вы фактически теряете память! Смотрите это для углубленного обсуждения.
Манагарм

@Managarm Предпосылка этого поста заключается в том, что статическая переменная останется даже после того, как процесс (в данном случае, Activity) будет уничтожен. Однако, если надлежащая уборка дома выполнена, это не проблема ... поэтому я обнуляю ссылку в методе действия onDestroy ().
Джабари

@Jabari Ах, я пропустил часть onDestroy. В этом случае это не должно быть проблемой, хотя это не лучшая практика.
Манагарм

1
работал без проблем. Для api>=16использования finishAffinity()еще используйте этот метод.
Мистер Никто

4

Не одобряется ли выход из приложения? , Пройдите по этой ссылке. Это отвечает на ваш вопрос. Система выполняет работу по уничтожению приложения.

Предположим, у вас есть два действия A a B. Вы переходите от A к B. Когда вы нажимаете кнопку «Назад», ваше действие B извлекается из backstack и уничтожается. Предыдущее действие в заднем стеке A фокусируется.

Вы должны оставить это для системы, чтобы решить, когда убивать приложение.

общественная пустота finish()

Позвоните, когда ваша деятельность завершена и должна быть закрыта.

Предположим, у вас много занятий. Вы можете использовать панель действий. При нажатии на иконку дома перейдите к MainActivity вашего приложения. В MainActivity нажмите кнопку «Назад», чтобы выйти из приложения.


3

Для выхода из приложения вы можете использовать следующее:

getActivity().finish();
Process.killProcess(Process.myPid());
System.exit(1);

Также для остановки сервисов тоже вызовите следующий метод:

private void stopServices() {        
    final ActivityManager activityManager = SystemServices.getActivityManager(context);
    final List<ActivityManager.RunningServiceInfo> runningServices = activityManager.getRunningServices(Integer.MAX_VALUE);
    final int pid = Process.myPid();
    for (ActivityManager.RunningServiceInfo serviceInfo : runningServices) {
        if (serviceInfo.pid == pid && !SenderService.class.getName().equals(serviceInfo.service.getClassName())) {
            try {
                final Intent intent = new Intent();
                intent.setComponent(serviceInfo.service);
                context.stopService(intent);
            } catch (SecurityException e) { 
                 // handle exception
            }
        }
    }
}

2

Это может быть очень поздно, а также в соответствии с инструкциями, которые вы не должны обрабатывать процесс жизненного цикла самостоятельно (как ОС делает это для вас). Предполагается, что вы зарегистрируете радиовещательного приемника во всех своих действиях с помощью " finish()" в их onReceive() &, если вы хотите выйти, вы можете просто передать намерение, указывающее, что все действия должны быть закрыты ..... Хотя убедитесь, что вы это делаете " Отмените регистрацию получателя в ваших onDestroy()методах.


1

Это не хорошее решение, потому что оно противоречит принципам обработки приложений Android. Android не убивает никакой процесс, если он не является абсолютно неизбежным. Это помогает приложениям запускаться быстрее, потому что они всегда хранятся в памяти. Поэтому вам нужна особая причина, чтобы убить процесс вашего приложения.


4
Выйти из приложения требует действительно убить приложение. так что должен быть способ обеспечить завершение приложения после выхода из системы
anonim

1

Правильное и точное решение для выхода из приложения по нажатию кнопки - использовать следующий код:

// На кнопке Back нажал событие

public void onBackPressed()
{ 
   moveTaskToBack(true);
   finish();
}

Это довольно актуальный компонент Android (например, активность), а не все приложение .
Лаогеодрит

Это только отправит приложение в фоновом режиме
Кумар Гаурав

1

Если вы используете Kotlin, правильный способ выхода из приложения и альтернатива System.exit()- встроенный метод

exitProcess(0)

Смотрите документацию .

Число 0в качестве параметра означает, что выход предназначен и ошибки не произошло.


0

Это убьет все что угодно;)

int p = android.os.Process.myPid();
android.os.Process.killProcess(p);


0

Я нашел самый простой способ выйти из приложения из действия, не нарушая логику Android и не добавляя больше кода в существующие действия и передавая дополнения, это следующее:

public static void quitApplication (Activity currentActivity) {
    Intent intent = new Intent (currentActivity, QuitApplicationActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    currentActivity.startActivity (intent);
    currentActivity.finish ();
}

QuitApplicationActivityсущество:

public class QuitApplicationActivity extends AppCompatActivity {

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

        finish ();
    }
}

0

Ответ @Sivi закрывает приложение. Но по возвращении, если у вас есть какие-то дочерние действия, может быть открыто другое незаконченное действие. Я добавил noHistory:trueв свою деятельность, чтобы приложение по возвращении начиналось с MainActivity.

<activity 
      android:name=".MainActivity"
      android:noHistory="true">
</activity>

0

Просто чтобы добавить один в список жестоких методов завершения приложения:

Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL);


Process.killProcess(Process.myPid())делает то же самое, но короче
ivan8m8

-1

Вы можете выйти из своих полных приложений. таким образом

Intent intent = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage(getBaseContext().getPackageName());
intent .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

это будет работать на 100%. Удачи!


1
Это не кажется ответом на этот вопрос!
Аль-Мотафар

-4

Просто используйте финиш () на клавишу возврата, нажмите на клавишу ()


4
finish () закроет Activity, но точно не закроет все приложение с уверенностью.
2Dee,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.