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.