Android: Видаліть усі попередні дії зі зворотного стеку


119

Коли я натискаю кнопку « Вийти » у своїй активності профілю, я хочу перенести користувача на сторінку входу , де йому потрібно використовувати нові облікові дані.

Отже, я використав цей код:

Intent intent = new Intent(ProfileActivity.this,
        LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

у onButtonClickкнопці Вихід.

Але проблема полягає в тому, що коли я натискаю кнопку повернення пристрою в активності входу, це відводить мене до профілю. Я очікував, що програма закриється, коли я натискаю кнопку повернення пристрою на LoginActivity.

Що я роблю неправильно?

Я також додав android:launchMode="singleTop"у маніфест для моєї LoginActivity

Спасибі


@GauravVashisth я тільки після цього рішення stackoverflow.com/questions/5794506 / ...
Archie.bpgc

@ abbas.aniefa Це рішення я трохи складний. Це єдиний спосіб очистити весь задній стек. Тому що у мене є 30+ заходів, тому я повинен написати цей код трансляції для всіх
Archie.bpgc

спробуйте це тоді, stackoverflow.com/questions/10961481/… . Використання трансляції - краще рішення.
abbas.aniefa

інший підхід, який ви можете використовувати для виходу, коли ви виходите, зберігайте один прапор у спільних налаштуваннях і в кожному методі onRestart () діяльності ви можете перевірити це значення змінної, якщо воно встановлено на істинне, ви можете закінчити поточну активність. тож незалежно від того, скільки видів діяльності було відкрито в групі. це закінчило б всю вашу діяльність.
Хірен Дабхі

Ваш оригінальний код фактично працює для API рівня 11 або вище за допомогою налаштування. Вам просто потрібно поставити прапори разом в одному виклику: intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);я отримав відповідь від цього питання: stackoverflow.com/questions/3473168 / ...
jokeefe

Відповіді:


303

Пропоноване тут рішення спрацювало для мене:

Java

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Котлін

val i = Intent(this, NewActivity::class.java)
// set the new task and clear flags
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)

Однак для цього потрібен рівень API> = 11.


Хлопці, читайте документацію. FLAG_ACTIVITY_CLEAR_TASKЦе офіційний шлях. Не потрібно змінювати всі дії в додатку.
АлікЕльзін-кілака

Це не працює для сповіщень stackoverflow.com/questions/24873131/…
Sam

У мене є minAPI = 16, тому для мене це прекрасно працює. Однак я помітив, що виконання перегляду дещо мляве з API> 21 та плавне з API <21. Хтось із тією ж проблемою?
Червоний М

1
Це створить нове завдання для діяльності
Rohit

@kgiannakakis Без сумніву, рішення працює, якщо у нас є лише одне завдання (стек "Назад активності"), але коли у нас є кілька завдань (стек активності), воно не працює. Наприклад, скажімо, у мене є чотири дії для моєї програми A, B, C & D. Припустимо, у мене є дві активні стеки A-> B-> C (фон) та D-> A-> B (передній план) та якщо я активність виклику A з мого поточного стеку (D-> A-> B) з фільтром намірів, що ви запропонували, що станеться, очистіть мій поточний стек (D-> A-> B) і відкрийте активність A і коли я натискаю його назад закрити програми, але якщо натиснути кнопку останнього додатка, я можу побачити два зворотні стеки свого додатка.
Рахул Парета

31

Ось одне рішення для очищення всіх дій вашої програми, коли ви використовуєте кнопку виходу.

Кожен раз, коли ви починаєте діяльність, починайте її так:

Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class);
startActivityForResult(myIntent, 0);

Коли ви хочете закрити весь додаток, зробіть це:

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL - це підсумкова глобальна змінна з унікальним цілим числом, яке сигналізує про те, що ви хочете закрити всі дії.

Потім визначте onActivityResult(...)зворотний виклик кожної активності, тому коли активність повертається зі значенням RESULT_CLOSE_ALL, вона також викликає finish():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Це спричинить ефект каскаду, який закриє всі ваші дії.

Це, однак, хак і використовується startActivityForResultтаким чином, що він не був розроблений для використання.

Можливо, кращим способом це стане використання телевізійних приймачів, як показано тут:

Під час виходу очистіть стек історії активності, не дозволяючи кнопці "назад" відкривати активізовані лише вхідні дані

Дивіться ці теми також і для інших методів:

Android: очистити задній стек

Закінчіть усі попередні заходи


4
Чи це можливо, коли у вас є близько 30 заходів з історії ??
Ракеш Гондалія

4
має бути. Але якщо у вас є 30 видів діяльності в історії, ви можете подумати про зміну дизайну. 30 здається трохи надто багато, і Android може вбити їх самим.
Anup Cowkur

1
Це здається поганим способом це зробити. @RakeshGondaliya відповідь питання здається законним. 30 може бути просто числом, що представляє "велику" кількість заходів. Ця відповідь виглядає краще: stackoverflow.com/a/3008684/243709
Аман Алам

Ця відповідь чудова. Ви також можете використовувати бібліотеку EventBus для надсилання подій для вашої діяльності в backstack. github.com/greenrobot/EventBus
Стан

Краще використовувати простий прапор "Намір.FLAG_ACTIVITY_CLEAR_TOP" з наміром
Naveen Rao

18

Щоб повністю очистити стек активності, потрібно створити новий стек завдань за допомогою TaskStackBuilder, наприклад:

Intent loginIntent = LoginActivity.getIntent(context);
TaskStackBuilder.create(context).addNextIntentWithParentStack(loginIntent).startActivities();

Це не лише створить новий, чистий стек завдань, але також дозволить належним чином функціонувати кнопку "вгору", якщо у вашого LoginActivity є батьківська активність.


1
Це найкращий спосіб зробити це.
Пол Берк

FLAG_ACTIVITY_NEW_TASKабо finishAffinity()не працювали для мене. Тільки ця відповідь вирішила мету.
ТМ

Якщо я покину програму за допомогою кнопки "Назад" і повернусь за допомогою піктограми програми, вона відкриється в тій діяльності, яку я назвав цим методом. Так що для мене не працює.
Tgo1014

17

finishAffinity()додано в API 16. Використовувати ActivityCompat.finishAffinity()в попередніх версіях. Коли ви будете запускати будь-яку діяльність за допомогою намірів і закінчити поточну діяльність. Тепер використовуйте ActivityCompat.finishAffinity()замість цього finish(). він завершить всі складені дії нижче поточної активності. Це прекрасно працює для мене.


3
Це насправдіActivityCompat.finishAffinity()
Берга

finishAffinity()також завершує поточну активність усіма видами активності в задній стеці тієї ж спорідненості.
Neeraj Sewani

10

Що працювало на мене

Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

5

Одне з можливих рішень, що я можу вам запропонувати, - це додати android:launchMode="singleTop"до маніфесту для моєї профілюActivity . і коли натиснути вихід, ви можете вийти з системи, починаючи знову, ви LoginActivity. при виході ви можете це зателефонувати.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();

Я зробив це, що сталося так: коли я натискаю кнопку "назад", це переводить мене до Activty, звідки я прийшов до
ProfileActivity

Це може статися тому, що ви прийшли до ProfileActivity, викликавши новий намір, а не зателефонувавши на Fin (); Як ви переходите до профілюActivity з інших видів діяльності, крім LoginActivty?
Android

Я перетинаю те саме питання. Я думаю, що це не спрацює, коли наміри входу були зруйновані системою, скажімо, через відсутність пам’яті.
користувач1914692

5

Для API 11+ ви можете використовувати Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASKтак:

Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);

Це повністю очистить усі попередні види діяльності та розпочне нову діяльність.


4

Можна спробувати finishAffinity(), це закриває всі поточні дії та працює на Android 4.1 і вище


1
FinAffinity () додано в API 16. Використовуйте ActivityCompat.finishAffinity () у попередній версії. Я чудово працює для мене.
Анураг Шрівастава

2

Я також стикаюся з тим же питанням ..

в діяльності входу в систему, що я роблю.

    Intent myIntent = new Intent(MainActivity.this, ActivityLoggedIn.class);
    finish();
    MainActivity.this.startActivity(myIntent);  

на вихід

   Intent myIntent = new Intent(ActivityLoggedIn.this, MainActivity.class);
   finish();
   ActivityLoggedIn.this.startActivity(myIntent);

Це добре працює, але коли я перебуваю в ActivityLoggedIn і мінімізую додаток і натискаю на піктограму кнопки запуску на ящику програми, MainActivity запускається знову: - / я використовую прапор

android:LaunchMode:singleTask 

для MainActivity.


2

Використовуйте наступне для activity

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

видаліть прапор CLEAR_TASK для використання фрагмента.

Я сподіваюся, що це може скористатися для деяких людей.


1

Просто тримай

Intent intent = new Intent(ProfileActivity.this,
    LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

4
Не працює. Я все ще можу перейти до профілюActivity за допомогою кнопки "Назад"
Archie.bpgc

1

Жоден із прапорців намірів не працював на мене, але ось як я це виправив:

Коли користувач виходить з однієї діяльності, мені довелося транслювати повідомлення з цієї діяльності, а потім отримувати його в тих заходах, які я хотів закрити, після яких я закликаю закінчити (); і це працює досить добре.


1

Спробуйте це спрацює:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();

1

В рівні 11 або вище API використовуйте FLAG_ACTIVITY_CLEAR_TASKта FLAG_ACTIVITY_NEW_TASKпозначте на Намір, щоб очистити весь стек активності.

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |  Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

0

Використовуй це

Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

ви знали setFlags та addFlags?
GvSharma


0

Розширений, багаторазовий котлін:

Ви можете встановити прапор безпосередньо, використовуючи метод сеттера. У Котліні orє заміна Java побіжно або |.

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Якщо ви плануєте регулярно використовувати це, створіть функцію розширення намірів

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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.