- Как очистить стек Android-активности?
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Ответ 4
- Ответ 5
- Ответ 6
- Ответ 7
- Ответ 8
- Ответ 9
- Ответ 10
- Tasks и Back Stack в Android
- Маленький итог
- Управление тасками
- Атрибут launchMode
- Флаги
- Affinity
- Чистка стека
- Как очистить стек Android деятельности?
- 10 ответов
- Android: очистить стек активности
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Ответ 4
- Ответ 5
- Ответ 6
- Ответ 7
- Ответ 8
Как очистить стек Android-активности?
У меня есть приложение с несколькими действиями в Android, и я хочу, чтобы пользователь мог выйти из системы, нажав кнопку меню. Проблема в том, что
A) Android не позволяет прекратить действие приложения и B), даже когда я снова отправлю пользователя в LoginActivity , они всегда могут вернуться назад и вернуться к предыдущему действию, в котором они находились.
Я уже пытался запустить Activity с двумя следующими флагами:
Я также пробовал с каждым из них самостоятельно.
Я также попробовал позвонить finish() после startActivity(intent) , как я прочитал в другом StackOverflow вопрос.
ОТВЕТЫ
Ответ 1
В вашей активности входа переопределите кнопку «Назад», чтобы она скрывала ваше приложение, а не завершала действие:
Также не забудьте установить android: alwaysRetainTaskState = «true» в корневой активности, поэтому Android не очищает ваш стек (включая активность входа) после 30 минут бездействия от пользователя.
Затем просто вызовите finish(), когда есть успешный вход в систему.
Ответ 2
Это должно быть побитовое ИЛИ или вы в конечном итоге перезаписываете ранний флаг.
Ответ 3
Ответ 4
Если вы используете Android API 11 или выше, вы можете использовать следующий код для очистки стека.
Ответ 5
Это не очистит стек вашей активности.
Даже после выполнения всего вышеприведенного ответа, когда я нажал кнопку «Назад», он показывал последнее действие за секунду до закрытия приложения.
Это то, что я сделал:
Теперь мое приложение выходит на задний экран:) без каких-либо проблем.
Ответ 6
Настройка Intent.FLAG_ACTIVITY_CLEAR_TOP сработала для меня в очень похожем случае, когда я не установил флаг Intent.FLAG_ACTIVITY_NEW_TASK . Вы пробовали без?
Ответ 7
Эта работа для меня:)
Где A — моя корневая активность, например
У меня есть действия A → B → C → D, когда я вызываю начальную активность E в стеке У меня есть A → E
Я не знаю, это хорошо:) но работает.
Ответ 8
напишите это и обратите внимание: LoginActivity должен быть запущен сначала как Launcher и
если вы пишете какие-либо режимы запуска, флаги перезаписывают свою цель, поэтому удалите launchermode и попробуйте, вы обязательно получите его
Ответ 9
Ответ 10
Если мы используем этот код для запуска активности входа (A):
Активность должна быть в стеке действий, иначе эти флаги не будут иметь никакого эффекта.
Если мы используем функцию finish() в активности входа (A), после запуска активности (B) (чтобы избежать возврата к A из B), активность A (Login) не будет находиться в стеке. Точно так же происходит, когда в активности входа в качестве атрибута «noHistory».
Итак, решение для меня было сочетанием других ответов:
Этот код переходит в действие B, чтобы не возвращаться к активности входа:
И этот код переходит в действие, вызывающее функцию выхода:
Источник
Tasks и Back Stack в Android
Итак. Каждое Android приложение, как минимум, состоит из фундаментальных объектов системы — Activity. Activity — это отдельный экран который имеет свою отдельную логику и UI. Количество Activity в приложении бывает разное, от одного до много. При переходах между различными Activity пользователь всегда может вернуться на предыдущую, закрытую Activity при нажатии кнопки back на устройстве. Подобная логика реализована с помощью стека (Activity Stack). Его организация «last in, first out» — т.е. последний вошел, первый вышел. При открытии новой Activity она становится вершиной, а предыдущая уходит в режим stop. Стек не может перемешиваться, он имеет возможность добавления на вершину новой Activity и удаление верхней текущей. Одна и та же Activity может находиться в стеке, сколько угодно раз.
Task — это набор Activity. Каждый таск содержит свой стек. В стандартной ситуации, каждое приложение имеет свой таск и свой стек. При сворачивании приложения, таск уходит в background, но не умирает. Он хранит весь свой стек и при очередном открытии приложения через менеджер или через launcher, существующий таск восстановится и продолжит свою работу.
Ниже покажу картинку, как работает стек.
Если продолжать нажимать кнопку back, то стек будет удалять Activity до того, пока не останется главная корневая. Если же на ней пользователь нажмет back, приложение закроется и таск умрет. Кстати, я говорил о том, что когда мы сворачиваем наше приложение и запускам например новое, то наш таск просто уходит в background и будет ждать момента, пока мы его вызовем. На самом деле есть одно «но». Если мы будем иметь много задач в background или же просто сильно нагружать свое устройство, не мала вероятность того, что таск умрет из за нехватки системных ресурсов. Это не война конечно, но то что мы потеряем все наши текущие данные и наш стек очистится — это точно. Кстати для избежания потери данных в таком случаи, вам стоит почитать про SavingActivityState.
Маленький итог
Управление тасками
Существует два пути для изменения стандартной организации тасков. Мы можем устанавливать специальные атрибуты в манифесте для каждой Activity. Также мы можем устанавливать специальные флаги для Intent, который запускает новую Activity с помощью startActivity(). Заметьте, что иногда атрибуты в манифесте и флаги в Intent могут противоречить друг другу. В этом случаи флаги Intent будут более приоритетны.
Атрибут launchMode
Для каждой Activity в манифесте можно указать атрибут launchMode. Он имеет несколько значений:
- standard — (по умолчанию) при запуске Activity создается новый экземпляр в стеке. Activity может размещаться в стеке несколько раз
- singleTop — Activity может распологаться в стеке несколько раз. Новая запись в стеке создается только в том случаи, если данная Activity не расположена в вершине стека. Если она на данный момент является вершиной, то у нее сработает onNewIntent() метод, но она не будет пересоздана
- singleTask — создает новый таск и устанавливает Activity корнeвой для него, но только в случаи, если экземпляра данной Activity нет ни в одном другом таске. Если Activity уже расположена в каком либо таске, то откроется именно тот экземпляр и вызовется метод onNewIntent(). Она в свое время становится главной, и все верхние экземпляры удаляются, если они есть. Только один экземпляр такой Activity может существовать
- singleInstance — тоже что и singleTask, но для данной Activity всегда будет создаваться отдельный таск и она будет в ней корневой. Данный флаг указывает, что Activity будет одним и единственным членом своего таска
На самом деле не важно, в каком таске открыта новая Activity. При нажатии кнопки back мы все равно вернемся на предыдущий таск и предыдущие Activity. Единственный момент, который нужно учитывать — это параметр singleTask. Если при открытии такой Activity мы достанем ее из другого background таска, то мы полностью переключаемся на него и на его стек. на картинке ниже это продемонстрировано.
Флаги
Как и говорил, мы можем устанавливать специальный флаги для Intent, который запускает новую Activity. Флаги более приоритетны, чем launchMode. Существует несколько флагов:
- FLAG_ACTIVITY_NEW_TASK — запускает Activity в новом таске. Если уже существует таск с экземпляром данной Activity, то этот таск становится активным, и срабатываем метод onNewIntent().
Флаг аналогичен параметру singleTop описанному выше - FLAG_ACTIVITY_SINGLE_TOP — если Activity запускает сама себя, т.е. она находится в вершине стека, то вместо создания нового экземпляра в стеке вызывается метод onNewIntent().
Флаг аналогичен параметру singleTop описанному выше - FLAG_ACTIVITY_CLEAR_TOP — если экземпляр данной Activity уже существует в стеке данного таска, то все Activity, находящиеся поверх нее разрушаются и этот экземпляр становится вершиной стека. Также вызовется onNewIntent()
Affinity
Стандартно все Activity нашего приложения работают в одном таске. По желанию мы можем изменять такое поведение и указывать, чтобы в одном приложении Activity работали в разных тасках, или Activity разных приложений работали в одном. Для этого мы можем в манифесте для каждой Activity указывать название таска параметром taskAffinity. Это строковое значение, которое не должно совпадать с названием package, т.к. стандартный таск приложения называется именно как наш пакет. В общем случаи данный параметр указывает, что Activity будет гарантированно открываться в своём отдельном таске. Данный параметр актуален, если мы указываем флаг FLAG_ACTIVITY_NEW_TASK или устанавливаем для Activity атрибут allowTaskReparenting=«true». Этот атрибут указывает, что Activity может перемещаться между тасками, который её запустил и таском, который указан в taskAffinity, если один из них становится активным.
Чистка стека
Если таск долгое время находится в background, то система сама чистит его стек, оставляя только корневую Activity. Данное поведение обусловлено тем, что пользователь может забыть, что он делал в приложении до этого и скорее всего зашел в него снова уже с другой целью. Данная логика также может быть изменена с помощью нескольких атрибутов в манифесте.
- alwaysRetainTaskState — если флаг установлен в true для корневой Activity, то стек не будет чиститься и полностью восстановится даже после длительного времени
- clearTaskOnLaunch — если установить флаг в true для корневой Activity, то стек будет чиститься моментально, как только пользователь покинет таск. Полная противоположность alwaysRetainTaskState
- finishOnTaskLaunch — работает аналогично clearTaskOnLaunch, но может устанавливаться на любую Activity и удалять из стека именно её
Это всё для данного топика. Статья не импровизированная, а по сути является вольным переводом официальной документации. Рекомендую собрать легкий пример и поэксперементировать с флагами и атрибутами. Некоторые моменты, лично для меня были, неожиданно интересными. любые ошибки и недоработки учту в лс. Спасибо.
Источник
Как очистить стек Android деятельности?
у меня есть приложение с несколькими действиями в Android, и я хочу, чтобы пользователь мог выйти из системы, нажав кнопку меню. Проблема в том, что
A) Android не позволяет завершить работу приложения и
B) даже когда я отправляю пользователя в LoginActivity снова они всегда могут нажать назад и вернуться к предыдущей деятельности, в которой они были.
Я уже пытался запустить действие с двумя следующими флагами:
Я также пробовал с каждым из них самостоятельно.
Я также пытался позвонить finish() после startActivity(intent) как я читал в другом сайте StackOverflow вопрос.
10 ответов
в вашей активности входа в систему переопределите кнопку «назад», чтобы она скрывала ваше приложение вместо завершения действия:
также не забудьте установить android: alwaysRetainTaskState=»true» в корневой активности, поэтому Android не очищает ваш стек (включая активность входа) после 30 минут бездействия от пользователя.
затем просто вызовите finish (), когда есть успешный вход в систему.
Это должно быть побитовым или вы в конечном итоге перезаписываете более ранний флаг.
добавить android:noHistory=»true» атрибут на AndroidManifest.xml такой:
Если вы используете Android API 11 или выше, вы можете использовать следующий код, чтобы очистить стек.
это не очистит ваш стек активности.
даже после выполнения всего вышеизложенного ответа, когда я нажал кнопку «назад», он показал последнее действие за секунду до закрытия приложения.
вот что я сделал:
теперь мое приложение выходит на задний пресс 🙂 без каких-либо хлопот.
задание Intent.FLAG_ACTIVITY_CLEAR_TOP работал для меня в очень похожем случае, когда я не установил Intent.FLAG_ACTIVITY_NEW_TASK флаг. Вы пробовали без него?
эта работа для меня 🙂
где A-моя корневая активность, например
У меня есть действия A — > B — > C — > D Когда я вызываю start activity E в стеке, у меня теперь есть A — > E
Я не знаю, хорошо ли это:) но работает.
напишите это и обратите внимание: LoginActivity должен быть запущен сначала как Launcher и
Если вы пишете какие-либо режимы запуска, флаги перезаписываются, поэтому удалите launchermode и попробуйте, вы обязательно получите его
Если мы используем этот код для запуска действия входа (A):
действие должно быть в стеке действий, иначе эти флаги не будут иметь никакого эффекта.
Если мы используем finish () в действии входа в систему (A), после запуска действия (B) (чтобы избежать возврата к A из B), действие A (вход в систему) не будет в стеке. Точно так же происходит, когда действие входа в систему имеет атрибут «noHistory».
Итак, решение для меня было смесью другие ответы:
этот код входит в действие B, чтобы избежать возврата к активности входа:
и этот код входит в действие, которое вызывает функцию выхода из системы:
Источник
Android: очистить стек активности
У меня есть несколько действий в моем приложении. и поток очень сложный. Когда я нажимаю приложение Logout naviagates для входа в экран входа в систему, и оттуда пользователь может выйти, отменив бутон (вызов system.exit(0) )
когда я выхожу из или назад, система вызывает действие из стека: (как я могу очистить все действия в стеке, когда я нахожусь на экране входа в систему? вызов finish() нецелесообразен, так как существует так много действий и некоторых действий не должны быть закрыты, когда они активны, например, активность активации вызываемой камеры.
ОТВЕТЫ
Ответ 1
Большинство из вас ошибаются. Если вы хотите закрыть существующий стек операций независимо от того, что там и создать новый root, правильный набор флагов следующий:
public static final int FLAG_ACTIVITY_CLEAR_TASK
Добавлено в уровень API 11
Если задано в Intent, переданном Context.startActivity() , этот флаг вызовет любую существующую задачу, которая будут связаны с активностью, подлежащей очистке до начинается деятельность. То есть, эта деятельность становится новым корнем иначе пустая задача, и все старые действия завершены. Это может используется только в сочетании с FLAG_ACTIVITY_NEW_TASK .
Ответ 2
Когда вы вызываете startActivity в последнем действии, вы всегда можете использовать
как флаг этого намерения.
Подробнее о флагове здесь.
Ответ 3
Вот простой вспомогательный метод для запуска нового действия в качестве новой верхней активности, которая работает с уровня API 4 до текущей версии 17:
назовите это следующим образом:
Ответ 4
Очистить активность Backstate по нижнему коду:
Готово
Ответ 5
В моем случае LoginActivity также был закрыт. В результате
Ответ 6
Ответ 7
Я отметил, что вы попросили решение, которое не полагается на finish() , но мне интересно, может ли это тем не менее помочь.
Я отслеживал, возникает ли флаг выхода с переменной статического класса, которая выживает во всей продолжительности жизни приложения. В каждом соответствующем действии onResume() используйте
Скажем, в mainActivity, пользователь нажимает кнопку для выхода — вы можете установить ExitHelper.isExitFlagRaised = true; , а затем finish() . После этого также будут завершены другие соответствующие виды деятельности, которые будут возобновлены автоматически.
Ответ 8
Это решение отлично работает:
Но новый запуск активности длится, и вы видите белый экран некоторое время. Если это важно, используйте этот обходной путь:
Как это использовать:
Недостаток: все действия, которые должны быть закрыты в стеке, должны расширять BaseActivity
Источник