Android: открыть активность без сохранения в стек


94

У меня 2 вида деятельности: Основное и Список.

Из Главного вы можете открыть Список; из списка вы можете открыть Main.

Я хотел бы это так , чтобы каждое открытие списка никак не спасется в «истории». Таким образом, возврат из Main не может вернуться в список.

Является ли это возможным?


11
Если 'list' запускает 'main', то finish()сразу после этого он будет вызван startActivity(...). Таким образом, если пользователь нажмет BACK из «main», вернуться будет не к чему.
— Squonk

это для навигации по уведомлениям, но концепции могут быть применимы developer.android.com/guide/topics/ui/notifiers/…
— Кевин Ли,

Ответы:


160

При запуске списка Activityустановите его Intentфлаги следующим образом:

Intent i = new Intent(...); // Your list's Intent
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); // Adds the FLAG_ACTIVITY_NO_HISTORY flag
startActivity(i);

FLAG_ACTIVITY_NO_HISTORYФлаг держит новый Activityот добавления в стек истории.

NB: как указывает @Sam, вы можете использовать i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);вместо этого. Функциональной разницы нет.


2
Небольшой комментарий к этому методу: этот будет отлично работать, если есть только 2 Activity. Но если действие списка способно запустить другое действие (скажем, третье действие), нажатие кнопки возврата в третьем
— действии

На самом деле. К сожалению, избежать этого невозможно. Нет Intentфлага, который гласит, что «только добавляет в историю, если не возвращается к Activityисходной точке».
— Эрик

1
нет, но флаг FLAG_ACTIVITY_NEW_TASK выполнит свою работу, список Activity будет добавлен в историю, но всегда вверху, поэтому при обратном нажатии из основного Activity не будет отображаться список Activity
— VinceFR

7
Есть ли какая - либо конкретная причина , вы использовали setFlags()с getFlags()вместо Intent.addFlags()?
— Sam

1
@VinceFR это именно то, что я хочу! a -> b -> c и вернуться прямо к c-
— realtebo

90

В файле манифеста добавьте:

android:noHistory="true" 

к деятельности, которую вы не хотите хранить в стеке.


есть ли разница от начала активности с флагом no_history?
— realtebo

1
Как вы сказали в своем вопросе, «каждое открытие списка НЕ ​​сохраняется в« истории ». Поэтому всякий раз, когда вы снова открываете свое приложение, это приведет вас к основному действию
— Марчин С.

@MarcinS. когда приложение отсутствует в списке последних приложений, оно не работает. Не могли бы вы объяснить, почему это происходит?
— Аджит Кумар Дубей

1
Итак, в чем разница между этими двумя подходами (манифест и флаг)?
— pumbosha

Подход @pumbosha Manifest всегда будет исключать активность из истории. Флаговый подход позволяет вам контролировать это поведение во время выполнения.
— Джон Кроуфорд

27

Воспользуйтесь новой задачей с очисткой. Это сработало в моем случае, когда другие варианты не работали.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Очистите весь стек истории и начните новое действие на Android


1
Это было бы здорово, но есть ли способ остановить резкую анимацию «смены задачи»? К сожалению, добавление FLAG_ACTIVITY_NO_ANIMATION не мешает этому!
— androidguy

это влияет на скорость работы приложения?
— Acauã Pitta

23

Похоже, что если вы вызываете finish () для своей активности сразу после того, как открыли другую, завершенная удаляется из стека.

например:

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

Если ваш телефон работает не так быстро, вы увидите, что предыдущая активность уходит.
— Нолан

@Nolan, это только если вы закончите до того, как начнете деятельность
— Хенрик Бёгелунд Лавсцен,

7

В моем конкретном случае FLAG_ACTIVITY_NO_HISTORYне сработало. Ни не работали, FLAG_ACTIVITY_NEW_TASKни FLAG_ACTIVITY_CLEAR_TASKсами по себе.

Однако FLAG_ACTIVITY_NEW_TASKи FLAG_ACTIVITY_CLEAR_TASKвместе работали.

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

4

Поздний ответ, но добавляет глубины другим ответам. Все сводится к тому, что вы хотите сделать с другими действиями, начатыми с этого действия.

Вариант 1. Только это одно действие не должно иметь истории вызовов.

Тогда просто сделайте:

Intent i = new Intent(...);
i.addFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

Вариант 2. Все действия, начатые с этого конкретного действия, не должны иметь истории

Затем добавьте в манифест вызывающей активности:

android:noHistory="true" 

Но если вы действительно хотите иметь историю в новом действии, вам нужно вручную удалить флаг:

Intent i = new Intent(...);
i.removeFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

Надеюсь, что это проясняет другие ответы :)


3

Просто хотел добавить способ сделать это в Котлине:

val i = Intent(this, LogInActivity::class.java)
startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK))

2
Больше в стиле Котлина: Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) }.also { startActivity(it) }
— 4ndro1d

2

Попробуйте FLAG_ACTIVITY_CLEAR_TOP, если действие уже выполняется:

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


-4

Разве вы не можете переопределить кнопку «Назад» на конкретном действии, чтобы остановить функцию «возврата»?

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {

        return true;
    }
    return super.onKeyDown(keyCode, event);
}

6
Не делай этого. Приемлемо перехватывать BACK для определенных целей, но делать это исключительно для того, чтобы беззвучно потреблять нажатие BACK и предотвращать завершение не Activityявляется хорошей практикой.
— Squonk

1
Полностью согласен ^ только вариант.
— Broak

1
Для этого есть OnBackPressed.
— Фред
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.