Android: відкрити активність без збереження в стеку


94

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

З головного ви можете відкрити список; зі списку ви можете відкрити головну.

Я хотів би, щоб кожне відкриття Списку не зберігалося в "історії". Отже, натискання назад від Main не може повернутися до списку.

Це можливо?


11
Якщо "список" починається з "main", нехай він дзвонить finish()відразу після цього startActivity(...). Таким чином, якщо користувач натисне НАЗАД із «головного», не буде до чого повертатися.
Squonk

це для навігації сповіщень, але ці концепції можуть бути застосовними developer.android.com/guide/topics/ui/notifiers/…
Кевін Лі

Відповіді:


159

Під час запуску списку 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 може запустити інше Activity (скажімо, третє Activity), натискання кнопки назад у третьому Activity повернеться до основного Activity, а не списку Activity
VinceFR

Справді. На жаль, цього неможливо уникнути. Немає Intentпрапора, який би зазначав, що "лише додає історію, якщо не повертається до Activityджерела походження".
Ерік

1
ні, але прапор FLAG_ACTIVITY_NEW_TASK зробить роботу, список Діяльність буде доданий до історії, але завжди вгорі, тому натискання
головою

7
Чи є якась - або конкретна причина , ви використовували setFlags()з getFlags()замість Intent.addFlags()?
Сем

1
@VinceFR це саме те, що я хочу! a -> b -> c і поверніться безпосередньо до c-
realtebo

89

У файл маніфесту додайте:

android:noHistory="true" 

до діяльності, яку ви не хочете тримати в стеку.


чи є якась різниця від початку активності з прапором no_history?
realtebo

1
Як ви сказали у своєму запитанні "кожне відкриття списку НЕ зберігається в" історії ". Тому кожного разу, коли ви знову відкриваєте свою заявку, це приведе вас до основної діяльності
Marcin S.

@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

Здається, якщо ви зателефонуєте завершенню () у вашій діяльності одразу після того, як ви відкрили інше, те, що закінчено, видаляється зі стеку.

наприклад:

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);

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,

3

Пізня відповідь, але додає певної глибини іншим відповідям. Все зводиться до того, що ви хочете, щоб сталося з іншими заходами, розпочатими з цієї діяльності

Варіант 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);

Сподіваюся, що це прояснить інші відповіді :)


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
Не роби цього. Прийнятно перехоплювати НАЗАД для конкретних цілей, але робити це виключно для того, щоб тихо споживати БЕКС-прес і запобігати припиненню дії не Activityє доброю практикою.
Squonk

1
Погодьтеся повністю ^ просто варіант.
Broak

1
Для цього є OnBackPressed.
Фред
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.