Android: очистить задний стек
В Android у меня есть некоторые действия, скажем, A, B, C.
В AI используйте этот код, чтобы открыть B:
Intent intent = new Intent(this, B.class);
startActivity(intent);
В BI используйте этот код для открытия C:
Intent intent = new Intent(this, C.class);
startActivity(intent);
Когда пользователь нажимает кнопку в CI, я хочу вернуться к A и очистить задний стек (закройте B и C). Поэтому, когда пользователь нажимает кнопку возврата B и C не отображаются, я пробовал следующее:
Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Но B и C по-прежнему отображаются, если я использую кнопку "Назад", когда возвращаюсь к занятию A. Как я могу избежать этого?
39 ответов
Попробуйте добавить 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);
finish(); // call this to finish the current activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Как насчет добавления в файл манифестов для связанной деятельности:
android:noHistory="true"
к определению активности B и C? Они не будут добавлены в backstack. Не уверен, что это то, что вы хотите.
Это беспокоит меня долгое время. Наконец я решил это, выполнив это:
Во фрагменте используйте:
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);
Начиная с API 16 (Jelly Bean), вы можете просто позвонить finishAffinity()
,
Теперь вы также можете позвонить ActivityCompat.finishAffinity(Activity activity)
с библиотекой совместимости.
Обязательно задайте для taskAffinity в манифесте имя пакета, уникальное для этой группы действий.
Смотрите для получения дополнительной информации:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html
- добавлять
android:launchMode="singleTop"
к элементу активности в вашем манифесте для Действия A - Тогда используйте
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
а такжеintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
при запуске упражнения А
Это означает, что при запуске действия A все задачи поверх него очищаются, так что A находится наверху. Новый задний стек создается с A в корне, и с использованием singleTop
гарантирует, что вы только когда-либо запускаете A один раз (так как A сейчас на вершине из-за ..._CLEAR_TOP
).
Попробуйте использовать
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
и не
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Если ваше приложение имеет минимальную версию 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
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.
Используйте finishAffinity(); в задаче C при запуске задачи A для очистки операций обратного стека.
Согласно Aitor Gómez в Удаление деятельности из стека истории...
добавлять android:noHistory="true"
приписать к вашему <activity>
в AndroidManifest.xml
как это:
<activity android:name=".MyActivity"
android:noHistory="true">
</activity>
Для будущих исследований попробуйте этот код.
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();
Используйте этот код для начала новой активности и закройте или уничтожьте все остальные стеки активности или задний пакет...
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
В котлине это почти так же, как в Java. Только | символ заменяется на или текст. Итак, это написано как
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
Я нашел интересное решение, которое может помочь. Я сделал это в моем onBackPressed()
метод.
finishAffinity();
finish();
FinishAffinity
удаляет подключение существующего действия к его стеку. А потом финиш поможет вам выйти из этого занятия. Который в итоге выйдет из приложения.
Продвинутый, повторно используемый Котлин:
Вы можете установить флаг напрямую, используя метод setter. В Котлине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
}
Для меня это звучит так, как будто тебе нужно начать Activity C
от Activity B
используя startActivityForResult()
, Когда вы нажимаете кнопку в Activity C
, вызов setResult(RESULT_OK)
а также finish()
так Activity C
Я отправил. В Activity B
Вы могли бы иметь onActivityResult()
ответить также позвонив finish()
на себя, и вы бы тогда вернулись к Activity A
,
Я нашел ответы здесь немного вводящими в заблуждение, потому что код в оригинальном вопросе, кажется, работает хорошо для меня?
Поскольку A является корневым действием, запуск его с B или C только с FLAG_ACTIVITY_CLEAR_TOP приводит к удалению B и C из заднего стека.
Я перепробовал все решения, и ни одно из них не сработало индивидуально Мое решение:
декларировать 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();
Intent.FLAG_ACTIVITY_CLEAR_TOP
не будет работать в этом случае. Пожалуйста, используйте (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
Для более подробной информации, пожалуйста, ознакомьтесь с этой документацией.
Пример Kotlin:
val intent = Intent(this@LoginActivity, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
finish()
logout.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Для меня добавление 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();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Вы можете использовать этот пример, чтобы позвонить 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);
После этого вы не получите никаких действий, нажав кнопку "Назад":
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finishAffinity();
finish();
Данный код работает правильно. Я пробовал в образце жизненного цикла приложения.
У меня нет B и C в заднем стеке после начала действия A с флагом FLAG_ACTIVITY_CLEAR_TOP
Это сработало для меня с onBackPressed:
public void onBackPressed()
{
Intent intent = new Intent(ImageUploadActivity.this, InputDataActivity.class);
Intent myIntent = new Intent(this, ImageUploadActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
Я звонил activity_name.this.finish()
после начала нового намерения, и это сработало для меня.
I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"
Но он не будет работать для меня... Я не предлагаю это решение для использования, но если установка флага не будет работать для вас, чем вы можете попробовать это... Но все же я рекомендую не использовать его
Вот как я решил проблему:
private boolean clearHistoryBackStack = true;
@Override
public final void finish() {
super.finish();
if(clearHistoryBackStack)
finishAffinity();
}