Android: очистити задній стек


330

В Android я займаюся деякими видами діяльності, скажімо, A, B, C.

У A я використовую цей код, щоб відкрити B:

Intent intent = new Intent(this, B.class);
startActivity(intent);

У B я використовую цей код, щоб відкрити C:

Intent intent = new Intent(this, C.class);
startActivity(intent);

Коли користувач натискає кнопку в C, я хочу повернутися до A і очистити задній стек (закрити B і C). Тож коли користувач натискає кнопку B і C назад, не з’являється, я намагаюся зробити таке:

Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

Але B і C все ще з'являються, якщо я використовую кнопку "назад", коли я повертаюся в активі А. Як я можу цього уникнути?

Відповіді:


438

Спробуйте додати, FLAG_ACTIVITY_NEW_TASKяк описано в документах для FLAG_ACTIVITY_CLEAR_TOP:

Цей режим запуску також може бути використаний для хорошого ефекту в поєднанні з FLAG_ACTIVITY_NEW_TASK: якщо він використовується для запуску кореневої активності завдання, він виведе на передній план будь-який запущений екземпляр цього завдання, а потім очистить його до його кореневого стану. Це особливо корисно, наприклад, під час запуску діяльності від менеджера сповіщень.

Отже ваш код для запуску Aбуде:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
CurrentActivity.this.finish(); // if the activity running has it's own context


// view.getContext().finish() for fragments etc.

28
Дякую, але я спробував це. Тим не менше, коли я натискаю кнопку "назад" після того, як вона знову відображає C. Що я можу бракувати?
Мартін

4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
dzeikei

8
не працює для мене, однак виклик закінчувати () на вихідну діяльність робить те, що мені потрібно було досягти
2cupsOfTech

10
У мене була така ж проблема, що це не працює. Для мене це було зателефонувати після закінчення нової діяльності
Арно

20
Я також додав ще один чіткий намір наміру = новий намір (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (наміри); закінчити ();
Сем

147
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

8
Зважаючи на CLEAR_TOPпрапор - ця комбінація є ТІЛЬКИМ, яка повністю очистила весь стек і зробила нову діяльність єдиною в додатку. Дякую!
Авіель Гросс

8
Чим відрізняється ця відповідь від прийнятої відповіді?
Юрій Хеупа

7
Дякую, відмінність від прийнятої відповіді полягає в тому, що з цим прапором нам не потрібно дзвонити на
Activity.finish

1
FLAG_ACTIVITY_CLEAR_TASK прекрасно працював разом з NEW_TASK
Шамсул Арефін Саджіб

1
Це має бути прийнятою відповіддю. Дуже дякую.
доктор наук Ансарі

77

Як щодо додавання у файл маніфестів для пов’язаної діяльності:

android:noHistory="true"

до активності визначення B і C? Вони не будуть додані до рюкзака. Не впевнений, чи це ви хочете.


3
Будьте дуже обережні, використовуючи це - якщо ви використовуєте логін з FB або будь-який подібний функціонал
Skynet

2
@Skynet Чому? Які проблеми пов'язані з цим?
Alfie Woodland

8
Коли ви передаєте управління ФБ для входу зі сторінки, яка є істинною, як правда, додаток FB тепер не куди приземлитися після входу користувача, у моєму випадку він повертався на головний екран телефону, і я майже втратив роботу!
Скайнет

Це не дає активності, доданої до backstack .... це неправильне рішення.
Тарун

Саме я шукаю
Masum

63

Це мене довго турбує. Насправді я працював над цим:

У фрагменті використовуйте:

Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

У розділі Діяльність використовуйте (додайте ще один прапор наміру Intent.FLAG_ACTIVITY_CLEAR_TASKпорівняно з фрагментом):

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

1
Якщо ви використовуєте андроїданотації, вам потрібно додати: Намір.FLAG_ACTIVITY_CLEAR_TASK
yosafatade

Активність солютіоїну добре працювала для мене. Хоча я вважаю, що за допомогою API 16 рішення Даніеля Шулера простіше.
PhilippS

Дякую вам йосафатаде, саме цього мені не вистачало!
Марті Міллер

30
  1. Додайте android:launchMode="singleTop"до елемента активності у вашому маніфесті для діяльності А
  2. Потім використовуйте intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) і intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)при запуску Діяння А

Це означає, що при запуску діяльності A всі завдання, що знаходяться на ній, очищаються, так що A - зверху. Створено новий задній стек з A в корені, а використання singleTopдозволяє запускати лише колись один раз (оскільки A тепер на вершині завдяки ..._CLEAR_TOP).


3
Так. це те, що я зараз використовую, але це не робить. Ще C з'являється, коли натискаю кнопку "назад".
Мартін

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

Я перезапустив емулятор і тепер, здається, працює так, як ви сказали. Велике спасибі за вашу допомогу!
Мартін

SingleTop не повинен мати нічого спільного з очищенням стека.
stdout

29

Починаючи з API 16 (Jelly Bean), можна просто зателефонувати finishAffinity().

Тепер ви також можете телефонувати ActivityCompat.finishAffinity(Activity activity)з бібліотекою сумісності.

Не забудьте встановити taskAffinity у маніфесті до імені пакета, унікального для цієї групи діяльності.

Докладнішу інформацію див. На веб-сторінці:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


Дійсно корисне і просте рішення, якщо ви ознайомилися з API 16. Працювали для мене!
PhilippS

3
нагадування: це буде працювати лише для дій, які мають одне й те саме завдання Назва назви
Райан,

це працює лише в тому випадку, якщо у вас є лише одна діяльність в історії.
arsent


11

Якщо у вашій програмі є мінімальна версія 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



8

Для майбутніх досліджень спробуйте цей код.

Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();

Ці прапори нарешті спрацювали для мене. Що я і робив, я розпочав ту саму діяльність, якою займався з цими прапорами та булевим додатковим EXIT = true. В inCreate () я перевірив параметри запуску для EXIT і викликав закінчення (), якщо він був встановлений істиною. Це багато клопоту, просто щоб закрити власний додаток.
Janne Oksanen

8

Використовуйте FinAffinity (); у завданні C при запуску завдання А для очищення операцій із заднім числом.


тільки ця відповідь працює для мене. Намір.FLAG_ACTIVITY_CLEAR_TOP і Intent.FLAG_ACTIVITY_NEW_TASK не потрібні
горіховий лоток

7

Використовуйте цей код для запуску нової діяльності та закрийте або знищуйте всі інші стеки активності чи зворотні стеки.

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

5
Use finishAffinity() to clear all backstack with existing one.

Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 

    - Activity B will be finished / removing from stack.
    - Activity A will be finished / removing from stack.
    - Activity C will finished / removing from stack.

5

Я знайшов цікаве рішення, яке може допомогти. Я зробив це за своїм onBackPressed()методом.

finishAffinity();
finish();

FinishAffinityвидаляє підключення існуючої діяльності до її стека. А потім закінчити допоможе вам вийти з цієї діяльності. Який з часом вийде з програми.


4

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

Якщо A є кореневою діяльністю, починаючи її з B або C лише за допомогою FLAG_ACTIVITY_CLEAR_TOP, вилучає B і C із заднього стека.


4

У котліні він майже такий, як java. Тільки | символ замінюється на текст або текст. Отже, написано як-

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

3

Я спробував усі рішення, і жоден не працював індивідуально для мене. Моє рішення:

Заявляйте Activity Aяк SingleTopза допомогою [android:launchMode="singleTop"]маніфесту Android.

Тепер додайте наступні прапори під час запуску Aз будь-якого місця. Це очистить стек.

Intent in = new Intent(mContext, A.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(in);
finish();

2

Intent.FLAG_ACTIVITY_CLEAR_TOPв цьому випадку не працюватиме. Будь ласка, використовуйте(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Більш детально ознайомтеся з цією документацією.


2

Мені це звучить так, що потрібно починати Activity Cз Activity Bвикористання startActivityForResult(). Коли ви натискаєте кнопку в Activity C, дзвінок setResult(RESULT_OK)і finish()так Activity Cзакінчується. В Activity B, ви могли б onActivityResult()відповісти, також викликаючи finish()на себе, і ви б потім бути прийняті назад Activity A.


7
Так, але якщо між А і С буде 42 заходи, це буде досить втомливо. Прапор FLAG_ACTIVITY_CLEAR_TOP повинен робити безпосередньо те, що хоче ОП.
Гійом Брунері

Це був би менш оптимальним способом досягнення того, чого хоче ОП, і, як сказав @Guillaume, він вимагатиме коду у всіх видах діяльності між коренем і вершиною стека.
Джейк Базіле

Належним чином відзначено. Це прапори, про які мені, мабуть, потрібно дізнатися.
Максим


1

Ви можете використовувати цей приклад для дзвінка Activity AзActivity C

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);


1

для мене додавання Intent.FLAG_ACTIVITY_CLEAR_TASKвирішило проблему

Intent i = new Intent(SettingsActivity.this, StartPage.class);
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
finish();

1

Розширений, багаторазовий котлін:

Ви можете встановити прапор безпосередньо, використовуючи метод сеттера. У Котліні orце заміна Java побіжно або |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Якщо використовувати це не один раз, створіть функцію розширення намірів

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

Потім ви можете безпосередньо зателефонувати до цієї функції перед запуском наміру

intent.clearStack()

Якщо вам потрібна опція для додавання додаткових прапорів в інших ситуаціях, додайте додатковий параметр до функції розширення.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

0

Крім цього FLAG_ACTIVITY_CLEAR_TOP, ви можете спробувати додати Intent.FLAG_ACTIVITY_SINGLE_TOPтакож:

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


Це вплине лише на активність у верхній частині стека, а не на корені.
Джейк Базіле

0

Даний код працює правильно. Я спробував у зразку життєвого циклу програми.

У мене не було B і C в задній стеці після початку активності A зі прапором, FLAG_ACTIVITY_CLEAR_TOP


0

Я зателефонував activity_name.this.finish()після початку нового наміру, і він працював на мене.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

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


0

Додайте прапор НІ історії в намірі.

У діяльності B запустіть активність C, як показано нижче >>>>>>

Intent intent = new Intent(this, C.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
startActivity(intent);
finish();

0

У маніфесті

android:launchMode="singleTask"

і

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

0

Або додайте це до свого Activity BтаActivity C

android:noHistory="true"

або Override onBackPressedфункцію, щоб уникнути натискання назад за допомогою a return.

@Override
public void onBackPressed() {
   return;
}

0

Використовуйте метод setFlags () для чіткої задньої сторони, відкрийте всю активність і закрийте свою активність

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.