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 по-прежнему отображаются, если я использую кнопку «Назад», когда возвращаюсь к занятию A. Как я могу избежать этого?

Мартин
источник

Ответы:

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
у меня ничего не получается, однако вызов
метода
10
У меня была та же проблема, что это не работало. Для меня было исправлено вызывать метод finish () после начала нового действия
Арно
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
Pablo Cegarra
1
FLAG_ACTIVITY_CLEAR_TASK отлично работали вместе с NEW_TASK
Шамсул Арефин Саджиб
1
Это должен быть принятый ответ. Большое спасибо.
Доктор медицины датский Ансари
77

Как насчет добавления в файл манифеста для связанной деятельности:

android:noHistory="true"

к определению активности B и C? Они не будут добавлены в backstack. Не уверен, что это то, что вы хотите.

Доминик Хеллеберг
источник
3
Будьте очень осторожны при использовании этого - если вы используете логин с FB или любой подобный тип функциональности
Skynet,
2
@Skynet Почему? Какие проблемы связаны с этим?
Alfie Woodland
8
Когда вы передаете управление в FB для входа со страницы с неисторией как истиной, приложение FB теперь не имеет, куда приземлиться после входа пользователя, в моем случае оно возвращалось на домашний экран телефона, и я почти потерял свою работу!
Скайнет
Это не позволяет деятельности добавить в backstack .... это не правильное решение.
Тарун
Точно я ищу
Масум
63

Это беспокоит меня долгое время. Наконец я решил это, выполнив это:

Во фрагменте используйте:

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

В Activity используйте (добавьте еще один флаг намерения 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);
Geng Jiawen
источник
1
Если вы используете андроидные аннотации, вы должны добавить: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade
Активность solutioin работала нормально для меня. Хотя я думаю, что с API 16 решение от Даниэля Шулера проще.
PhilippS
Спасибо yosafatade, это было то, что мне не хватало!
Марти Миллер
30
  1. Добавьте android:launchMode="singleTop"к элементу активности в манифесте для действия A
  2. Затем используйте intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) и intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)при запуске действия A

Это означает, что при запуске действия A все задачи поверх него очищаются, так что A находится наверху. Новый задний стек создается с A в корне, и использование singleTopгарантирует, что вы только когда-либо запускаете A один раз (так как A теперь находится на вершине из-за ..._CLEAR_TOP).

Джозеф Эрл
источник
3
Да. это то, что я сейчас использую, но это не так. Все еще C появляется, когда я нажимаю кнопку "Назад".
Мартин
Странно, я использовал это в проекте, и он работает нормально ... нажатие назад возвращает меня на домашний экран. Возможно, что-то еще происходит. Не могли бы вы опубликовать свой манифест?
Джозеф Эрл
Я перезапустил эмулятор, и теперь он, кажется, работает так, как вы сказали. Большое спасибо за твою помощь!
Мартин
singleTop не должен иметь ничего общего с очисткой стека.
выход
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
напоминание: это будет работать только для действий, в которых используется одно и то же имя задачи
Райан
это работает, только если у вас есть только одно действие в истории.
пришло
17

Попробуйте использовать

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

и нет

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Мухаммед Амир Али
источник
11

Если ваше приложение имеет минимальную версию SDK 16, то вы можете использовать finishAffinity ()

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

Для меня это работа. На экране 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();
GeetT
источник
Эти флаги наконец-то сработали для меня. То, что я сделал, я запустил ту же активность, в которой находился, с этими флагами и логическим дополнительным EXIT = true. В onCreate () я проверил параметры запуска для EXIT и вызвал finish (), если было установлено значение true. Это много хлопот, чтобы просто закрыть свое приложение.
Янне Оксанен
8

Используйте finishAffinity (); в задаче C при запуске задачи A для очистки операций обратного стека.

baswaraj
источник
только этот ответ работает для меня. Intent.FLAG_ACTIVITY_CLEAR_TOP и Intent.FLAG_ACTIVITY_NEW_TASK не требуются
Nuttynibbles
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 из заднего стека.

ianjoyner
источник
4

В котлине это почти так же, как в Java. Только | символ заменяется на или текст. Итак, это написано как

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
Exigente05
источник
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();
Tarun
источник
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.

Maximus
источник
7
Да, но если между А и С есть 42 действия, это будет довольно утомительно. Флаг FLAG_ACTIVITY_CLEAR_TOP должен делать то, что хочет OP.
Гийом Брунери
Это было бы неоптимальным способом достижения того, что хочет OP, и, как сказал @Guillaume, потребовался бы код во всех действиях между корнем и вершиной стека.
Джейк Бэзил
Верно подмечено. Это флаги, о которых я должен узнать, по-видимому.
Максим
1

logout.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);

Abhijeet
источник
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

Продвинутый, многоразовый Kotlin:

Вы можете установить флаг напрямую, используя метод установки. В Kotlin orесть замена для битовой Java или |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Если вы используете это более одного раза, создайте функцию расширения Intent

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
}
Gibolt
источник
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

Sathesh
источник
0

я позвонил activity_name.this.finish()после начала нового намерения, и это сработало для меня.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

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

Своп-IOS-Android
источник
0

Добавьте NO Флаг Истории в намерении.

В упражнении 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функция, чтобы избежать обратного нажатия с return.

@Override
public void onBackPressed() {
   return;
}
Ренджит JR
источник
0

Используйте метод setFlags (), чтобы очистить заднюю сторону, открыть все действия, закрыть и запустить yourActvity.

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Панкадж Талавия
источник