Закінчіть усі попередні заходи


368

У моїй програмі є наступні екрани потоку:

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

Зараз у мене є загальна log out кнопка на кожному екрані

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

Я хочу, що коли користувач натисне кнопку виходу (з будь-якого екрана), всі екрани будуть закінчені і Log inвідкриється новий екран .

Я намагався FLAG_ACTIVITYдосягти цього майже всіх . Я також проходжу декілька відповідей у ​​stackoverflow, але не маючи змоги вирішити проблему. Мій додаток працює на Android 1.6, тому його не можна використовуватиFLAG_ACTIVITY_CLEAR_TASK

Чи є спосіб вирішити питання?


Чи проводите ви вкладені дії за допомогою startActivityForResult?
Вудші

ні. Усі заходи розпочинаються із запускуActivity.
Tanmay Mandal

Я використовую вкладені дії, коли треска виконує finishaffinitytask () у вкладеній діяльності. це змінює поведінку? як іноді я отримую невдачу, що дає результат ResultInfo, коли працює finishaffinitytask.
Ріпал Тамболі

Будь ласка , перевірте цю відповідь, це, безсумнівно , допоможе вам stackoverflow.com/a/25159180/2732632
Kimmi Dhingra

3
Android 21 представив Activity.finishAndRemoveTask ().
Джозеф Джонсон

Відповіді:


543

Використання:

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

Це дозволить очистити всі заходи на дому.

Якщо припустити, що ви закінчуєте екран входу, коли користувач увійде в систему та створиться домашня сторінка, а потім усі екрани від 1 до 5 зверху. Код, який я опублікував, поверне вас на головний екран, закінчивши всі інші дії. Ви можете додати додатковий у намірі і прочитати, що це в домашньому екрані, і закінчити його (можливо, знову запустіть екран входу звідти чи щось).

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

Сподіваюсь, це допомагає.


Користувач показує свій перший екран як домашній екран, ось головне питання.
Tanmay Mandal

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

10
Замість того, щоб заявити про діяльність як singleInstance, розгляньте використання FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOPяк прапорів для наміру. Це закінчить втручаються заходи і розпочне (або поверне на перший план) бажану діяльність.
CommonsWare

13
@ CommonsWare Додавання intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);до моєї діяльності мені не допомогло. Я не завершив втручаються дії. Коли я натискаю назад з екрана входу, я бачу попередні дії. Тут мій код Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
Tanmay Mandal

26
цей код очищає лише верхній стек активності, щоб очистити всі дії intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
Аджай Венугопаль

318

Ви можете спробувати Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Це повністю очистить усі попередні види діяльності та розпочне нову діяльність.


11
Правильне рішення, але лише API 11+
riwnodennyk

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

2
@riwnodennyk чому API 11+?
Мухаммед Бабар

17
Використовуйте IntentCompat.FLAG_ACTIVITY_CLEAR_TASK для попередніх 11 версій
Стівен Пена

2
@ono Так. Це має бути все, що вам потрібно. Переконайтесь, що в маніфесті режим запуску цільової активності встановлено як "singleTask".
Стівен Пена

137

Перш ніж запустити нову діяльність, просто додайте наступний код:

finishAffinity();

Або якщо ви хочете, щоб він працював у попередніх версіях Android:

ActivityCompat.finishAffinity(this);

12
ActivityCompat.finishAffinity (це); викликає Activity.finish () для api <16. Отже, він не працюватиме.
Аамір Abro

1
@Beto Caldas, я сам підтвердив вихідний код, він не працюватиме для API <16, як згадував AamirAbro. Це просто закінчить діяльність, яку ви передаєте API <16.
HendraWD

39

Коли користувач хоче вийти з усіх відкритих дій , він повинен натиснути кнопку, яка завантажує першу Активність, яка запускається при запуску програми, очистити всі інші дії, а потім закінчити останню активність. Запустити такий код, коли користувач натисне кнопку виходу. У моєму випадку LoginActivityце перша діяльність в моїй програмі.

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

Наведений вище код видаляє всі види діяльності , за винятком LoginActivity. Потім помістіть наступний код усередину LoginActivity's onCreate(...), щоб прослухати, коли LoginActivityвін відтворений і переданий сигнал' EXIT ':

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

Чому так важко зробити кнопку виходу в Android?

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

Розробники ОС Android хочуть, щоб ваша програма змогла пережити несподіване вимкнення та вимкнення живлення телефону, і коли користувач перезапустить програму, вони підбираються там, де вони зупинилися. Таким чином, користувач може отримувати телефонний дзвінок під час використання вашої програми та відкривати карти, що вимагає звільнення вашої програми для отримання додаткових ресурсів.

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


31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Це буде працювати для всіх версій Android. Де IntentCompatклас додано в бібліотеку підтримки Android.


IntentCompat.FLAG_ACTIVITY_CLEAR_TASKне розпізнається, використовуйте Intentзамість IntentCompat.
CoolMind

30

Використовуйте наступне для діяльності

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

видаліть прапор CLEAR_TASK для використання фрагмента.

Я сподіваюся, що це може скористатися для деяких людей.


24

Я думаю, я спізнююсь, але відповідь проста і коротка. Існує метод FinAffinity () в Activity, який завершить поточну активність та всі батьківські дії, але він працює лише в Android 4.1 або новішої версії.

Для API 16+ використовуйте

finishAffinity();

Для нижче 16 використовуйте

ActivityCompat.finishAffinity(YourActivity.this);

Сподіваюся, це допомагає!


21

Від developer.android.com :

public void finishAffinity ()

Додано в рівень 16 API

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

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


19

Зі сторони, корисно знати.
Ця відповідь працює ( 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();

тоді як це не працює

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

.setFlags() замінює будь-які попередні прапори і не додає жодних нових прапорів .addFlags().

Так що це теж спрацює

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

Чудове пояснення про різницю між setFlag та addFlag, дякую
Пеланес

13

Якщо ваша програма має мінімальну версію sdk 16, то ви можете використовувати FinAffinity ()

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

Це робота для мене. На екрані Top Payment видалити всі активні резервні копії,

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

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


10

Я вирішив для цього рішення (я думаю, що знайшов його десь у Stack Overflow, але не пам’ятаю, тому спасибі тому, хто це робив в першу чергу):

З будь-якої вашої діяльності виконайте це:

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

Потім у вашій LoginActivity перезапишіть onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3
Зазвичай це дуже погана ідея, тому це може спрацювати, вона вводить контактну точку, яка може зламатися в майбутньому, і це буде важко налагодити. Я вам кажу з досвіду :)
Мартін Маркончіні

10

Щоб натиснути кнопку виходу на останньому екрані програми, використовуйте цей код на слухачі кнопки виходу, щоб закінчити всі відкриті попередні дії, і ваша проблема буде вирішена.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}

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

6
чому FLAG_ACTIVITY_CLEAR_TASK двічі?
Чолецький

1
Як я розумію, .setFlags замінює попередні прапори і не додає жодних прапорів. .addFlags - це те, що ви хотіли використовувати, я припускаю? Викличте весь код вище i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); отримує знищені
iOSAndroidWindowsMobileAppsDev

addFlags працює для мене
Jamil

1
setFlagsзамінить усі попередні, тому останній setFlagsдіє лише попередній. Тож вам не потрібно дзвонитиi1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
mtrakal

8

У мене є IntentCompatтака ж проблема, яку ви можете використовувати , як це:

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

цей код працює для мене.

Android api 17


8

У моєму випадку я використовую finishAffinity()функцію в останній діяльності, наприклад:

finishAffinity()
startHomeActivity()

Сподіваюся, це стане в нагоді.



6

Увійдіть -> Головна-> екран 1-> екран 2-> екран 3-> екран 4-> екран 5

на екрані 4 (або будь-який інший) ->

StartActivity (Увійти)
з
FLAG_ACTIVITY_CLEAR_TOP


2
Коли я натискаю кнопку "назад", всі попередні дії відображаються в тому порядку, в якому вони були. Ті дії потрібно закрити, коли натиснута кнопка виходу, у стеку буде лише одна активність, і це буде активізація входу. І немає екран входу. Користувач починається з головного екрану.
Tanmay Mandal

6

для API> = 15 для API 23 просте рішення.

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

Сформулюйте свою відповідь, щоб кожен мав користь від неї.
Шубхамой

5

Якщо ви використовуєте startActivityForResult()в своїх попередніх заходах, просто переозначте OnActivityResult()і зателефонуйте finish();методу всередині нього у всіх видах діяльності. Це зробить роботу ...


Ні, я використовую startActivityлише
Tanmay Mandal

Це буде важко підтримувати onActivityResultв кожній діяльності. Я реалізував пропозицію DArkO і досяг моєї мети і дякую за допомогу.
Tanmay Mandal

3

Коли користувач натискає кнопку виходу, тоді напишіть наступний код:

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

А також коли після входу в систему, якщо ви зателефонували на нову діяльність, не використовуйте закінчення ();


2

Просто, коли ви переходите з екрана входу, а не після завершення екрана входу.

А потім у всіх перехідних заходах використовуйте це для виходу з системи:

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

Це прекрасно працює.


1

Якщо ви ввійшли в систему screen 1і звідти переходите на інші екрани, використовуйте

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

Коли я натискаю кнопку назад, всі попередні дії відображаються в тому порядку, в якому вони були. Ці дії потрібно закрити, коли натиснута кнопка виходу, у стеку буде лише одна активність, і це буде дія входу.
Tanmay Mandal

Якщо ви хочете такої поведінки, вам доведеться переосмислити onKeyDownта onBackPressed(або onKeyDown, якщо ви хочете підтримувати версії Android <2.0) у кожній своїй діяльності (крім входу в систему), і startActivity(login)там, як показано вище.
Габріель Негут

У мене є кнопка, яка переведе мене на екран входу, закінчуючи всі дії в стеці. Чи можливо?
Tanmay Mandal

1

Я знайшов цей спосіб, він очистить усю історію та вийде

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

1

Я думаю, я спізнююсь, але відповідь проста і коротка. Існує метод FinAffinity () в Activity, який завершить поточну активність та всі батьківські дії, але він працює лише в Android 4.1 або новішої версії.

Для API 16+ використовуйте

закінчитиАфінність ();

Для нижче 16 використовуйте

ActivityCompat.finishAffinity (YourActivity.this);

Сподіваюся, це допомагає!

shareedit відповів 27 травня 18 року о 8:03

Акшай Тару


0

Я знайшов це рішення працювати на кожному пристрої, незважаючи на рівень API (навіть для <11)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);


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