Як вийти з програми Android


321

Я знайшов кілька кодів для програмного виходу з програми 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


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

Відповіді:


397

Оскільки API 16, ви можете використовувати метод FinAffinity, який, здається, досить близький до закриття всіх пов'язаних дій за своїм ім'ям та описом Javadoc:

this.finishAffinity ();

Закінчіть цю діяльність, а також усі дії безпосередньо під нею в поточному завданні, що мають однакову спорідненість. Зазвичай це використовується, коли додаток можна запустити до іншого завдання (наприклад, від ACTION_VIEW того типу вмісту, який він розуміє), і користувач використовував навігацію вгору, щоб вийти з поточної задачі і перетворити її на власне завдання. У цьому випадку, якщо користувач перейшов у будь-яку іншу діяльність другого додатка, усі вони повинні бути видалені з початкової задачі як частини перемикача завдань.

Зауважте, що це завершення не дозволяє вам надати результати попередньої діяльності, і виняток буде видано, якщо ви намагаєтесь це зробити.


З API 21 ви можете використовувати дуже схожу команду

закінчитиAndRemoveTask ();

Завершує всі дії з цим завданням і видаляє його зі списку останніх завдань.


28
Однозначно це правильна відповідь! Це не дуже вдале рішення для завершення роботи програми System.exit(0);. Спасибі за вашу відповідь! Нарешті я знайшов гідне рішення.
Антоніо

4
Чи знаєте ви, чи є інше рішення в API 14? Спасибі
Сценарій Кітті

2
Ви можете закінчити () кожну діяльність окремо, коли ви закриєте додаток або всередині життєвого циклу діяльності.
sivi

3
УВАГА! this.finishAffinity () закриває додаток, видаляючи його з пам’яті, тому ви не будете отримувати push-повідомлення тощо.
Tincho825

7
Це рішення працює в 99% випадків. Однак це не зруйнує процес, тому, наприклад, Кинджал не буде очищений. У тих рідкісних випадках, коли потрібно вбити процес, System.exit(0)це єдине рішення, яке працювало для мене.
Слав

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

це найкращий спосіб вийти з програми. !!!

Найкраще рішення для мене.


так, чудово працює! Доведеться зателефонувати цьому від MainActivity, щоб змусити його працювати!
mz87

Ідеальне рішення. Не потрібно припиняти процес, оскільки Android найкраще знає для управління пам'яттю. Однак це забезпечує рішення для завершення діяльності, а також виходу з програми для зручності користувача.
IAmTheSquidward

Ідеальне рішення дійсно. Виправлено безліч проблем. Дякую.
суперрусердо

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. Ви хочете, щоб користувач не переходив до попередньої активності вашого додатка? Ну, або налаштуйте його так, щоб це не було, або вам потрібна додаткова опція. Якщо більшу частину часу back = попередня активність працює, не став би користувач просто натискати додому, якщо він хоче зробити щось інше?
  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
Я повністю згоден з цим випадком використання. Також врахуйте мій захищений додаток, який повинен бути доступний у певному місці, і його слід найкраще закрити, якщо користувач перебуває в цьому місці. Що мені робити?
Сідвелл

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);
    }

}

Це найбільш відповідна відповідь, проте це злом. Виклик обробки в onCreate буде виглядати глянцево на більшості, якщо не на всіх пристроях.
DoruChidean

Хм, це хак, але не глюк. Перший вихід () ви зателефонуєте, він закінчується у всіх заходах із чітким верхом і завданнями, а потім закінчуйте себе. тут ви виходите
vivek

1
Не забудьте оголосити цей клас у своєму маніфесті. Хоча +1 за розумний хак.
Таслім Осені

Це спрацювало! проголосували
TuanDPH

17

Немає програми, що виходить з програми Android , SampleActivity.this.finish (); завершить поточну діяльність.

Коли ви переходите від однієї діяльності до іншої, продовжуйте закінчувати попередню

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

13

Перш за все, такий підхід вимагає мінімум Api 16.

Я розділю це рішення на 3 частини, щоб вирішити цю проблему ширше.

1. Якщо ви хочете вийти з програми в діяльності, скористайтеся цим фрагментом коду:

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. Якщо ви хочете вийти з програми в класі, що не належить до нього, і ви не можете отримати доступ до такої діяльності, як служба, я рекомендую вам використовувати 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 () діяльності.

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

Крім того, не забудьте зателефонувати на незареєстрований приймач методом активності onDestroy ()

mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);

Щоб вийти з програми, ви повинні надіслати трансляцію за допомогою LocalBroadcastManager, який я використовую у своєму класі PlayService, який розширює службу.

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

10

Ви можете використовувати finishAndRemoveTask ()з API 21

публічне недійсне завершенняAndRemoveTask ()

Завершує всі дії з цим завданням і видаляє його зі списку останніх завдань.


8

Це залежить від того, наскільки швидко ви хочете закрити додаток.

Захисний спосіб закрити додаток - закінченняAffinity ();

Він закриває додаток після завершення обробки. На це може знадобитися певний час. Якщо ви закриєте додаток таким чином і перезапустите його через короткий час, можливо, ваша нова програма запуститься в тому ж процесі. З усіма незакінченими процесами та одиночними об'єктами старої програми.

Якщо ви хочете бути впевнені, що ваш додаток закрито повністю, використовуйте 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". Створіть статичну змінну активності всередині класу для кожної діяльності, яку має ваша програма. Потім створіть статичний метод під назвою "закрити", який запустить finish()метод на кожній із цих змінних Activity, якщо вони НЕ нульові . Якщо у вас є основна / батьківська діяльність, закрийте її останньою:

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()встановіть статична змінна в класі App , рівних « 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

@Managarm Передумова цієї посади полягає в тому, що статична змінна залишатиметься навіть після того, як процес (у цьому випадку активність) був знищений. Якщо належне прибирання будинку зроблено, це не проблема ... звідси причина я зводить нанівець посилання в методі onDestroy () діяльності.
Джабари

@Jabari Ах, я пропустив частину onDestroy. У цьому випадку це не повинно бути проблемою, хоча це не найкраща практика.
Managarm

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

4

Чи кидає виклик заяву нахмурна? . Перейдіть за цим посиланням. Він відповідає на ваше запитання. Система виконує завдання вбивства програми.

Припустимо, у вас є дві дії A a B. Ви переходите від A до B. Коли ви натискаєте кнопку "назад", ваша активність B вискакує з рюкзака і знищується. Попередня активність у активній активності стека 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
вихід із програми вимагає дійсно знищити додаток. тому має бути спосіб переконатись, що додаток загинув після його виходу
анонім

1

Правильним і точним рішенням для виходу з програми при натисканні кнопки є використання наведеного нижче коду:

// Подія натиснутої кнопки "Назад"

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

Просто натисніть клавішу закінчення () на задній клавіші, натисніть клавішу onKeypression ()


4
закінчення () закриє активність, але, безумовно, не закриє весь додаток із впевненістю.
2Dee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.