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

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

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 для достижения этой цели. Я также прошёл несколько ответов в stackru, но не смог решить проблему. Мое приложение на Android 1.6, поэтому не может использовать FLAG_ACTIVITY_CLEAR_TASK

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

30 ответов

Решение

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

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

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

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

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

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

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

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

finishAffinity();

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

ActivityCompat.finishAffinity(this);

Когда пользователь желает выйти из всех открытых действий, он должен нажать кнопку, которая загружает первое действие, которое запускается при запуске приложения, очистить все остальные действия, а затем завершить последнее оставшееся действие. Запустите следующий код, когда пользователь нажимает кнопку выхода. В моем случае, 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.

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

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

finishAffinity();

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

ActivityCompat.finishAffinity(YourActivity.this);

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

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

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

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

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

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

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

На заметку, полезно знать
Этот ответ работает ( /questions/32669324/zavershit-vse-predyiduschie-dejstviya/32669356#32669356)

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

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

public void finishAffinity ()

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

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

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

Если ваше приложение имеет минимальную версию 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() функция в последнем действии, как:

finishAffinity()
startHomeActivity()

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

Решение, которое я реализовал для этого (я думаю, что где-то нашел его в 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 перезаписать на KeyDown:

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

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

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

Вместо того, чтобы использовать finish() просто используйте finishAffinity();

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

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

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

Android api 17

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

Для 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);

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

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

 StartActivity (Войти) 
с
 FLAG_ACTIVITY_CLEAR_TOP 

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

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

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

finishAffinity();

Для младше 16 используйте

ActivityCompat.finishAffinity(YourActivity.this);

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

shareedit 27 мая '18 в 11:032018-05-27 11:03

Акшай Тару

На уровне API 11 или выше используйте флаги FLAG_ACTIVITY_CLEAR_TASK и FLAG_ACTIVITY_NEW_TASK в Intent для очистки всего стека активности.

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

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

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

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

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

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

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

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

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

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

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

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

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

Если я выйду из системы, данные в моих общих настройках будут уничтожены / удалены.

С помощью любого из моих действий, таких как Home.java, я проверяю, есть ли в общих настройках данные, и в этом случае их не будет, потому что я уничтожил их, когда вышел из системы с одного из экранов. Следовательно, логика уничтожает / завершает это действие и возвращает меня к действию входа в систему. Вы можете воспроизвести эту логику во всех других ваших действиях.

Однако не забудьте выполнить эту проверку внутри onPostResume(), потому что это то, что вызывается, когда вы возвращаетесь в Home.java.

Пример кода ниже:

      @Override
protected void onPostResume() {
    SharedPreferences pref = this.getSharedPreferences("user_details", Context.MODE_PRIVATE);
    if (pref.getAll().isEmpty()){
        //Shared Preferences has no data.
        //The data has been deleted
        Intent intent = new Intent(getApplicationContext(), Login.class);
        startActivity(intent);
        finish();
        //Finish destroys that activity which in our case is the Home.java
    }


    super.onPostResume();
}

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

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

Лучший способ закрыть все предыдущие действия и очистить память

finishAffinity()
System.exit(0);

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

В Котлине так:

в другом действии (с некоторыми классами) в разделе Imports

      var activity:Activity?=null
    get() = field
    set(value) {
        field = value
    }

Затем, под onCreate

      activity=this

в MainActivity сейчас:

      activity?.finish()
Другие вопросы по тегам