Все действия в моем приложении требуют, чтобы пользователь был авторизован для просмотра. Пользователи могут выйти практически из любой активности. Это требование приложения. В любой момент, если пользователь выходит из системы, я хочу отправить пользователя в логин Activity
. На данный момент я хочу, чтобы это действие было в нижней части стека истории, чтобы при нажатии кнопки «назад» пользователь возвращался на домашний экран Android.
Я видел, как этот вопрос задавали в нескольких разных местах, все отвечали схожими ответами (которые я обрисовал здесь), но я хочу поставить его здесь, чтобы собрать отзывы.
Я попытался открыть действие входа в систему, установив его Intent
флаги, FLAG_ACTIVITY_CLEAR_TOP
которые, как кажется, описываются в документации, но не достигает моей цели - поместить действие входа в конец стека истории и не позволяет пользователю вернуться назад. к ранее увиденным вошедшим в систему действиям. Я также пытался использоватьandroid:launchMode="singleTop"
для входа в активность в манифесте, но это также не достигает моей цели (и, похоже, в любом случае не имеет никакого эффекта).
Я считаю, что мне нужно либо очистить стек истории, либо завершить все ранее открытые действия.
Один из вариантов состоит в том, чтобы иметь onCreate
статус входа для каждой проверки активности , иfinish()
если нет - для входа. Мне не нравится эта опция, так как кнопка «Назад» все еще будет доступна для использования, навигация назад, когда действия закрываются.
Следующим вариантом является сохранение LinkedList
ссылок на все открытые действия, которые статически доступны из любого места (возможно, с использованием слабых ссылок). При выходе я получу доступ к этому списку и переберу все ранее открытые действия, вызываяfinish()
на каждое из них. Я, вероятно, скоро начну реализовывать этот метод.
Однако я бы предпочел использовать некоторую Intent
хитрость для флага. Я был бы очень рад обнаружить, что могу выполнить требования своего приложения, не используя ни один из двух методов, которые я описал выше.
Есть ли способ сделать это с помощью Intent
настроек или манифеста, или мой второй вариант - поддерживать LinkedList
открытые действия? Или есть другой вариант, который я полностью пропускаю?
Похоже, что новый программист Android проводит целый день, исследуя эту проблему и читая все эти потоки StackOverflow. Сейчас я только что инициирован и оставляю здесь след своего скромного опыта, чтобы помочь будущему паломнику.
Во-первых, нет никакого очевидного или немедленного способа сделать это согласно моему исследованию.
(as of September 2012).
Вы могли бы подумать, что можете просто,startActivity(new Intent(this, LoginActivity.class), CLEAR_STACK)
но нет .Вы можете сделать
startActivity(new Intent(this, LoginActivity.class))
сFLAG_ACTIVITY_CLEAR_TOP
- и это заставит рамки для поиска вниз по стеку, вы найдете ранее оригинальный экземпляр LoginActivity, воссоздать его и очистить остальную часть (вверх) стека. А поскольку логин находится, вероятно, в нижней части стека, у вас теперь есть пустой стек, а кнопка «Назад» просто выходит из приложения.НО - это работает, только если вы ранее оставили этот оригинальный экземпляр LoginActivity в основе своего стека. Если, как и многие программисты, вы выбрали
finish()
этоLoginActivity
после того, как пользователь успешно вошел в систему, то это больше не основано на стеке, иFLAG_ACTIVITY_CLEAR_TOP
семантика не применяется ... в итоге вы создаете новыйLoginActivity
поверх существующего стека. Это почти наверняка НЕ то, что вы хотите (странное поведение, когда пользователь может «вернуться» из входа в систему на предыдущем экране).Так что, если вы ранее
finish()
делали этоLoginActivity
, вам нужно использовать какой-то механизм для очистки стека и запуска новогоLoginActivity
. Похоже, что ответ@doreamon
в этой теме является лучшим решением (по крайней мере, на мой смиренный взгляд):https://stackoverflow.com/a/9580057/614880
Я сильно подозреваю, что хитрые последствия того, что вы оставите LoginActivity в живых, вызывают много этой путаницы.
Удачи.
источник
ОБНОВИТЬ
супер
finishAffinity()
метод поможет уменьшить код, но достичь того же. Он завершит текущее действие, а также все действия в стеке, используйте,getActivity().finishAffinity()
если вы находитесь во фрагменте.ОРИГИНАЛЬНЫЙ ОТВЕТ
Предположим, что LoginActivity -> HomeActivity -> ... -> Настройки CallAutOut ():
HomeActivity:
Это работает для меня, надеюсь, что это полезно и для вас. :)
источник
Если вы используете API 11 или выше, вы можете попробовать это:
FLAG_ACTIVITY_CLEAR_TASK
- Кажется, он решает именно вашу проблему. Очевидно, что толпа до API 11 должна была использовать некоторую комбинацию, когда все действия проверяют дополнительную, как предполагает @doreamon, или какую-то другую хитрость.(Также обратите внимание: чтобы использовать это, вы должны пройти
FLAG_ACTIVITY_NEW_TASK
)источник
finish();
сделает работу, чтобы предотвратить возвращение после выхода из системы. Зачем нужно устанавливать флаги?Я тоже потратил на это несколько часов ... и согласен с тем, что FLAG_ACTIVITY_CLEAR_TOP звучит так, как вы бы хотели: очистить весь стек, кроме запускаемого действия, чтобы кнопка «Назад» выходила из приложения. Тем не менее, как отметил Майк Репасс , FLAG_ACTIVITY_CLEAR_TOP работает только тогда, когда запускаемое вами действие уже находится в стеке; когда активности нет, флаг ничего не делает.
Что делать? Поместите запускаемое действие в стек с помощью FLAG_ACTIVITY_NEW_TASK , что делает это действие началом новой задачи в стеке истории. Затем добавьте флаг FLAG_ACTIVITY_CLEAR_TOP.
Теперь, когда FLAG_ACTIVITY_CLEAR_TOP отправляется на поиски нового действия в стеке, оно будет там и будет извлечено до того, как все остальное будет очищено.
Вот моя функция выхода из системы; Параметр View - это кнопка, к которой прикреплена функция.
источник
FLAG_ACTIVITY_CLEAR_TASK
он еще не был добавленМного ответов. Может быть, этот тоже поможет
Котлин версия-
источник
Используйте это, это должно быть полезно для вас. Слегка модифицированный ответ xbakesx.
источник
Принятое решение не является правильным, оно имеет проблемы, так как использование широковещательного приемника не является хорошей идеей для этой проблемы. Если ваша деятельность уже вызвала метод onDestroy (), вы не получите получателя. Лучшее решение - иметь логическое значение в ваших общих настройках и проверять его в методе onCreate () вашего актива. Если это не должно быть вызвано, когда пользователь не вошел в систему, тогда закончите деятельность. Вот пример кода для этого. Так просто и работает для любых условий.
источник
onResume()
. Потому что, когда вы нажимаете кнопку «Назад», действие, скорее всего, будет возобновлено, а не создано.Когда-то
finish()
не работаетЯ решил эту проблему с
finishAffinity()
источник
Я бы предложил другой подход к этому вопросу. Может быть, он не самый эффективный, но я думаю, что его проще всего применять и требует очень мало кода. Написание следующего кода в вашем первом действии (в моем случае, вход в систему) не позволит пользователю вернуться к ранее запущенным действиям после выхода из системы.
Я предполагаю, что LoginActivity завершается сразу после входа пользователя в систему, поэтому он не может вернуться к нему позже, нажав кнопку «Назад». Вместо этого пользователь должен нажать кнопку выхода из приложения внутри приложения, чтобы правильно выйти из системы. Эта кнопка выхода из системы реализует простое намерение:
Все предложения приветствуются.
источник
Выбранный ответ умный и хитрый. Вот как я это сделал:
LoginActivity - это корневая активность задачи, установите для нее android: noHistory = "true" в Manifest.xml; Скажем, вы хотите выйти из SettingsActivity, вы можете сделать это, как показано ниже:
источник
Вот решение, которое я нашел в своем приложении.
В моей функции LoginActivity после успешной обработки входа в систему я запускаю следующий по-разному в зависимости от уровня API.
Затем в методе onActivityForResult моего LoginActivity:
Наконец, после обработки выхода из любого другого действия:
Когда на Gingerbread, делает так, если я нажимаю кнопку «Назад» в MainActivity, LoginActivity сразу скрывается. На Honeycomb и более поздних версиях я просто заканчиваю LoginActivity после обработки имени входа, и оно правильно воссоздается после обработки выхода из системы.
источник
Это сработало для меня:
источник
Начните свою деятельность с StartActivityForResult, и пока вы выходите из системы, установите свой результат и, в соответствии с вашим результатом, завершите свою деятельность
источник
Предоставленное решение @doreamon отлично работает во всех случаях, кроме одного:
Если после входа в систему пользователь Killing Login перешел прямо к среднему экрану. Например, в потоке A-> B-> C, перейдите, как: Логин -> B -> C -> Нажмите ярлык для дома. Использование FLAG_ACTIVITY_CLEAR_TOP очищает только действие C, так как Home (A) отсутствует в истории стека. Нажатие Back на экране приведет нас к B.
Чтобы решить эту проблему, мы можем сохранить стек действий (Arraylist), и когда нажата кнопка home, мы должны убить все действия в этом стеке.
источник
Это возможно, управляя флагом в SharedPreferences или в Application Activity.
При запуске приложения (на заставке) установите флаг = false; При событии «Выйти из системы» просто установите флажок «истина» и в OnResume () каждой операции проверьте, установлен ли флажок «истина», затем вызовите finish ().
Работает как часы :)
источник
по клику выхода вы можете позвонить
onActivityResult () предыдущей операции, вызывайте этот код еще раз, пока вы не завершите все действия.
источник
То, что вы хотите сделать, это вызвать logout () и finish () для ваших методов onStop () или onPause (). Это заставит Android вызывать onCreate () при возобновлении активности, поскольку он больше не будет находиться в стеке своей активности. Затем сделайте, как вы говорите, в onCreate () проверьте статус вошедшего в систему и перейдите на экран входа в систему, если вы не вошли в систему.
Другая вещь, которую вы можете сделать, это проверить статус входа в систему в onResume (), а если не вошли в систему, finish () и запустить действие входа в систему.
источник