Завершить все предыдущие действия
Мое приложение имеет следующие экраны потока:
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()