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.