Завершить все предыдущие действия


368

Мое приложение имеет следующие экраны потока:

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Теперь у меня есть общая log out кнопка на каждом экране

( Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

Я хочу, чтобы, когда пользователь нажимал на кнопку выхода из системы (с любого экрана), все экраны были завершены, и Log inоткроется новый экран .

Я пытался почти все, FLAG_ACTIVITYчтобы добиться этого. Я также прошёл несколько ответов в stackoverflow, но не смог решить проблему. Мое приложение на Android 1.6, поэтому не может использоватьFLAG_ACTIVITY_CLEAR_TASK

Есть ли способ решить проблему?


Вы запускаете вложенные действия с помощью startActivityForResult?
— woodshy

Нет. Все действия начинаются с startActivity.
— Tanmay Mandal

Я использую вложенные действия, в то время как cod выполняет finishaffinitytask () во вложенных действиях. это меняет поведение? как иногда я получаю результат доставки результата ResultInfo при запуске finishaffinitytask.
— Рипал Тамболи

Пожалуйста, проверьте этот ответ, он, несомненно, поможет вам stackoverflow.com/a/25159180/2732632
— Кимми Дингра

3
Android 21 представил Activity.finishAndRemoveTask ().
— Джозеф Джонсон

Ответы:


543

Использование:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Это очистит все действия сверху дома.

Предполагая, что вы завершаете экран входа в систему, когда пользователь входит в систему и создается домашняя страница, а затем все экраны с 1 по 5 поверх этого. Код, который я разместил, вернет вас на главный экран и завершит все остальные действия. Вы можете добавить дополнительное в намерение и прочитать его на домашнем экране, а также завершить его (возможно, снова запустить экран входа в систему или что-то еще).

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

Надеюсь это поможет.


Пользователь показывает свой первый экран как домашний экран, вот в чем основная проблема.
— Tanmay Mandal

Хорошо, так как у меня есть мой ответ, вам нужно вернуться на домашний экран и закончить его. поэтому процесс вызывает намерение выше с любого экрана. получите намерение на главном экране и сразу же начните входить в систему и завершите работу после метода startActivity. Вы также можете переопределить ожидающую анимацию для нуля для входов и выходов, чтобы она не показывала переход (я делаю это, потому что он чувствует себя немного быстрее). Так что это должно работать нормально для того, что вам нужно.
— DArkO

10
Вместо того, чтобы объявить активность как singleInstance, рассмотрите возможность использованияFLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP в качестве флагов для Намерения. Это завершит промежуточные действия и начнет (или вернет на передний план) желаемое действие.
— CommonsWare

13
@ CommonsWare Добавление intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);к моим действиям не помогло мне. Оно не завершило промежуточные действия. Когда я нажимаю обратно с экрана входа в систему, я вижу предыдущие действия. Вот мой код Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
— Tanmay Mandal

26
этот код очищает только верхний стек действий для очистки всех действий intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
— Аджай Венугопал

318

Вы можете попробовать Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Это полностью очистит все предыдущие действия и начнет новую деятельность.


11
Правильное решение, но только API 11+
— riwnodennyk

Я использовал этот дополнительный флаг, так как он не вызывает задержку при отображении основного действия (он не перезапускается, поэтому работает намного быстрее).
— Маурицио

2
@riwnodennyk почему API 11+?
— Мухаммед Бабар

17
Используйте IntentCompat.FLAG_ACTIVITY_CLEAR_TASK для версий до 11
— Стивен Пена

2
@ono Да. Это должно быть все, что вам нужно. Убедитесь, что режим запуска вашей целевой активности установлен в манифесте как «singleTask».
— Стивен Пена

137

Прежде чем запускать новую активность, просто добавьте следующий код:

finishAffinity();

Или, если вы хотите, чтобы он работал в предыдущих версиях Android:

ActivityCompat.finishAffinity(this);

12
ActivityCompat.finishAffinity (это); Вызывает activity.finish () для API <16. Так что это не сработает.
— Амир Абро

1
@ Beto Caldas, я сам подтвердил исходный код, он не будет работать для API <16, как упомянул AamirAbro. Он просто завершит действие, которое вы передаете по API <16.
— HendraWD

39

Когда пользователь желает выйти из всех открытых действий , он должен нажать кнопку, которая загружает первое действие, которое запускается при запуске приложения, очистить все остальные действия, а затем завершить последнее оставшееся действие. Запустите следующий код, когда пользователь нажимает кнопку выхода. В моем случае LoginActivityэто первое действие в моей программе для запуска.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

Приведенный выше код очищает все действия, кроме LoginActivity. Затем поместите следующий код в LoginActivity's' onCreate(...), чтобы прослушивать, когда LoginActivityвоссоздается и передается сигнал 'EXIT':

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Почему создание кнопки выхода в Android так сложно?

Android изо всех сил пытается отговорить вас от наличия кнопки «выход» в вашем приложении, потому что они хотят, чтобы пользователь никогда не заботился о том, работают ли программы, которые они используют, в фоновом режиме или нет.

Разработчики ОС Android хотят, чтобы ваша программа выдерживала неожиданное отключение и отключение телефона, а когда пользователь перезапускает программу, он начинает с того места, на котором остановился. Таким образом, пользователь может получить телефонный звонок, пока он использует ваше приложение, и открыть карты, которые требуют освобождения вашего приложения для получения дополнительных ресурсов.

Когда пользователь возобновляет работу вашего приложения, он начинает работу с того места, где остановился, без перерыва. Эта кнопка выхода узурпирует власть менеджера активности, потенциально вызывая проблемы с автоматически управляемым жизненным циклом программы для Android.


31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Это будет работать для всех версий Android. Где IntentCompatкласс добавлен в библиотеку поддержки Android.


IntentCompat.FLAG_ACTIVITY_CLEAR_TASKне распознается, используйте Intentвместо IntentCompat.
— CoolMind

30

Используйте следующее для деятельности

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

убрать флаг CLEAR_TASK для использования фрагмента.

Я надеюсь, что это может использовать для некоторых людей.


24

Я думаю, что я опоздал, но есть простой и короткий ответ. В Activity есть метод finishAffinity (), который завершает текущее действие и все родительские действия, но работает только в Android 4.1 или новее.

Для API 16+ используйте

finishAffinity();

Для ниже 16, используйте

ActivityCompat.finishAffinity(YourActivity.this);

Надеюсь, поможет!


21

С сайта developer.android.com :

public void finishAffinity ()

Добавлено в API уровень 16

Завершите это действие, а также все действия непосредственно под ним в текущей задаче, которые имеют ту же привязку. Это обычно используется, когда приложение может быть запущено для другой задачи (например, из ACTION_VIEW типа контента, который он понимает), и пользователь использовал навигацию вверх для переключения из текущей задачи и в свою собственную задачу. В этом случае, если пользователь перешел к каким-либо другим действиям второго приложения, все они должны быть удалены из исходной задачи как часть переключения задачи.

Обратите внимание, что это завершение не позволяет вам доставлять результаты к предыдущему действию, и будет выдано исключение, если вы попытаетесь это сделать.


19

На заметку, полезно знать
Этот ответ работает ( https://stackoverflow.com/a/13468685/7034327 )

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

тогда как это не работает

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() заменяет любые предыдущие флаги и не добавляет новые флаги, пока.addFlags() делает.

Так что это тоже будет работать

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Отличное объяснение разницы между setFlag и addFlag, спасибо
— Pelanes

13

Если ваше приложение имеет минимальную версию SDK 16, то вы можете использовать finishAffinity ()

Завершите это действие, а также все действия непосредственно под ним в текущей задаче, которые имеют ту же привязку.

Для меня это работа. На экране Top Payment удалите все бэк-стеки,

@Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29


10

Решение, которое я реализовал для этого (я думаю, что где-то нашел его в Stack Overflow, но я не помню, так что спасибо тому, кто сделал это в первую очередь):

Из любой вашей деятельности сделайте это:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Затем в вашей LoginActivity перезаписать onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3
Обычно это очень плохая идея, хотя она может сработать, она вводит точку контакта, которая может сломаться в будущем, и ее будет трудно отлаживать. Я говорю вам из опыта :)
— Мартин Маркончини

10

Для кнопки выхода из системы на последнем экране приложения используйте этот код на слушателе кнопки выхода из системы, чтобы завершить все открытые предыдущие действия, и ваша проблема решена.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}

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

6
почему FLAG_ACTIVITY_CLEAR_TASK дважды?
— Choletski

1
Насколько я понимаю, .setFlags заменяет предыдущие флаги и не добавляет никаких флагов. Я полагаю, что вы хотели использовать .addFlags? Вызвать весь код выше i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); стирается
— iOSAndroidWindowsMobileAppsDev

addFlags работает для меня
— Джамиль

1
setFlagsзаменит все предыдущие, поэтому последний setFlagsдействителен, предыдущие заменяются. Так что вам не нужно звонитьi1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
— mtrakal

8

у меня есть та же проблема, которую вы можете использовать IntentCompat, как это:

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

этот код работает для меня.

Android api 17


8

В моем случае я использую finishAffinity()функцию в последнем действии как:

finishAffinity()
startHomeActivity()

Надеюсь, это будет полезно.



6

Войти-> Главный экран-> Экран 1-> Экран 2-> Экран 3-> Экран 4-> Экран 5

на экране 4 (или любой другой) ->

StartActivity (Войти)
с
FLAG_ACTIVITY_CLEAR_TOP


2
Когда я нажимаю кнопку «Назад», все предыдущие действия отображаются в том порядке, в котором они были. Эти действия должны быть закрыты, при нажатии кнопки выхода из системы в стеке будет только одно действие, и это будет действие входа в систему. Экран входа в систему. Пользователь запускается с домашнего экрана.
— Tanmay Mandal

6

для API> = 15 до API 23 простое решение.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

Разработайте свой ответ, чтобы каждый мог извлечь из этого пользу.
— Шубхамой

5

Если вы используете startActivityForResult()в своих предыдущих действиях, просто переопределите OnActivityResult()и вызовите finish();метод внутри него во всех действиях .. Это сделает работу ...


Нет, я использую startActivityтолько.
— Tanmay Mandal

Будет трудно поддерживать onActivityResultкаждый вид деятельности. Я выполнил предложение DArkO и достиг своей цели и благодарю за помощь.
— Танмей Мандал

3

Когда пользователь нажмет на кнопку выхода, напишите следующий код:

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

А также, когда после входа в систему, если вы вызываете новую деятельность, не используйте finish ();


2

Проще говоря, когда вы выходите из экрана входа в систему, а не после завершения экрана входа в систему.

И затем во всех последующих действиях используйте это для выхода из системы:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

Работает отлично.


1

Если вы вошли в систему пользователя screen 1и оттуда вы переходите на другие экраны, используйте

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

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

Если вы хотите это поведение, вы должны переопределить onKeyDownи onBackPressed(или onKeyDown, если вы хотите поддерживать версии Android <2.0) в каждом из ваших действий (кроме входа в систему), и startActivity(login)там, как показано выше.
— Габриэль Негут

У меня есть кнопка, которая выводит меня на экран входа в систему и завершает все действия в стеке. Возможно ли это?
— Tanmay Mandal

1

Я нашел этот путь, он очистит всю историю и выйдет

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);

1

Я думаю, что я опоздал, но есть простой и короткий ответ. В Activity есть метод finishAffinity (), который завершает текущее действие и все родительские действия, но работает только в Android 4.1 или новее.

Для API 16+ используйте

finishAffinity ();

Для ниже 16, используйте

ActivityCompat.finishAffinity (YourActivity.this);

Надеюсь, поможет!

shareedit ответил 27 мая '18 в 8:03

Акшай Тару


0

Я нашел это решение для работы на любом устройстве, несмотря на уровень API (даже для <11)

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


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