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

  1. добавлять android:launchMode="singleTop" к элементу активности в вашем манифесте для Действия A
  2. Тогда используйте 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();
}
Другие вопросы по тегам