Android как очистить backstack

Clear back stack using fragments

I ported my Android app to honeycomb and I did a big refactor in order to use fragments. In my previous version, when I pressed the Home button I used to do a ACTIVITY_CLEAR_TOP in order to reset the back stack.

Now my app is just a single Activity with multiple fragments, so when I press the Home button I just replace one of the fragments inside it. How can I clear my back stack without having to use startActivity with the ACTIVITY_CLEAR_TOP flag?

15 Answers 15

From Joachim’s answer, from Dianne Hackborn:

I ended up just using:

But could equally have used something like:

Which will pop all states up to the named one. You can then just replace the fragment with what you want

To make an answer for @Warpzit’s comment and make it easier for others to find.

With all due respect to all involved parties; I’m very surprised to see how many of you could clear the entire fragment back stack with a simple

According to Android documentation (regarding the name argument — the «null» in the claimed working proposals).

If null, only the top state is popped

Now, I do realize that I’m lacking knowledge of your particular implementations (like how many entries you have in the back stack at the given point in time), but I would bet all my money on the accepted answer when expecting a well defined behaviour over a wider range of devices and vendors:

(for reference, something along with this)

Works for me and easy way without using loop:

Clear backstack without loops

Where name is the addToBackStack() parameter

Accepted answer was not enough for me. I had to use :

I found a solution which is much better,from: https://gist.github.com/ikew0ng/8297033

I just wanted to add :—

Popping out from backstack using following

is just about removing the fragments from the transaction, no way it is going to remove the fragment from the screen. So ideally, it may not be visible to you but there may be two or three fragments stacked over each other, and on back key press the UI may look cluttered,stacked.

Just taking a simple example:-

Suppose you have a fragmentA which loads Fragmnet B using fragmentmanager.replace() and then we do addToBackStack, to save this transaction. So the flow is :—

STEP 1 -> FragmentA->FragmentB (we moved to FragmentB, but Fragment A is in background, not visible).

Now You do some work in fragmentB and press the Save button—which after saving should go back to fragmentA.

STEP 2-> On save of FragmentB, we go back to FragmentA.

STEP 3 ->So common mistake would be. in Fragment B,we will do fragment Manager.replace() fragmentB with fragmentA.

But what actually is happenening, we are loading Fragment A again, replacing FragmentB . So now there are two FragmentA (one from STEP-1, and one from this STEP-3).

Two instances of FragmentsA are stacked over each other, which may not be visible , but it is there.

Источник

Как очистить стек навигации после перехода к другому фрагменту в Android

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

Читайте также:  Iptv tv box android telegram

Пример: я нахожусь в loginFragment и хочу, чтобы этот фрагмент был очищен из стека, когда я перехожу к домашнему фрагменту, чтобы пользователь не возвращался обратно в loginFragment, когда он нажимает кнопку «Назад».

Я попытался использовать NavOptions в navigate () , но кнопка назад все еще отправляет меня обратно в loginFragment

Сначала добавьте атрибуты app:popUpTo=’your_nav_graph_id’ и app:popUpToInclusive=»true» в тег действия.

Во-вторых, перейдите к месту назначения, используя указанное выше действие в качестве параметра.

Дополнительную информацию см. В документации .

ПРИМЕЧАНИЕ . Если вы используете метод навигации navigate(@IdRes int resId) , вы не получите желаемого результата. Следовательно, я использовал метод navigate(@NonNull NavDirections directions) .

Я думаю, ваш вопрос конкретно касается того, как использовать Pop Behavior / Pop To / app: popUpTo (в xml)

В документации
всплывающее окно до указанного пункта назначения перед навигацией. Это выталкивает все несовпадающие места назначения из заднего стека, пока это место назначения не будет найдено.

Пример (простое приложение для поиска вакансий)
мой график start_screen_nav выглядит следующим образом:

если я хочу перейти EmployerMainFragment и вывести все, включая, startScreenFragment тогда код будет:

если я хочу перейти EmployerMainFragment и вывести все, исключая, startScreenFragment тогда код будет:

если я хочу перейти EmployerMainFragment и открыть, loginFragment но не startScreenFragment тогда, код будет:

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

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

ПРИМЕЧАНИЕ. Очистить задачу устарело, официальное описание

Этот метод устарел. Используйте setPopUpTo (int, boolean) с идентификатором графа NavController и установите для него значение true.

Старый ответ

Если вы не хотите пройти через весь этот пух в коде, вы можете просто проверить Clear Task в Launch Options в свойствах действия.

Изменить: начиная с Android Studio 3.2 Beta 5, очистить задачу больше не отображается в окне параметров запуска, но вы все равно можете использовать ее в XML-коде навигации, в теге действия , добавив

Источник

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.

Читайте также:  We are the robots для android

Маленький итог

Управление тасками

Существует два пути для изменения стандартной организации тасков. Мы можем устанавливать специальные атрибуты в манифесте для каждой 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, если один из них становится активным.

Читайте также:  Samsung mobile android versions

Чистка стека

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

  • alwaysRetainTaskState — если флаг установлен в true для корневой Activity, то стек не будет чиститься и полностью восстановится даже после длительного времени
  • clearTaskOnLaunch — если установить флаг в true для корневой Activity, то стек будет чиститься моментально, как только пользователь покинет таск. Полная противоположность alwaysRetainTaskState
  • finishOnTaskLaunch — работает аналогично clearTaskOnLaunch, но может устанавливаться на любую Activity и удалять из стека именно её

Это всё для данного топика. Статья не импровизированная, а по сути является вольным переводом официальной документации. Рекомендую собрать легкий пример и поэксперементировать с флагами и атрибутами. Некоторые моменты, лично для меня были, неожиданно интересными. любые ошибки и недоработки учту в лс. Спасибо.

Источник

Android: очистить все операции backstack, а затем завершить текущую активность

У меня разные действия в приложении, и поток очень сложный. Я хочу сделать это, как только устройство USB будет подключено, я хочу очистить и закончить действия в фоновом стеке, а затем завершить текущую активность и System.exit (0), чтобы закрыть приложение.

Я уже реализовал прослушиватель устройств usb. Я хочу знать, как очистить и завершить работу стека (если таковые имеются, он не будет иметь никаких операций с backstack каждый раз), а затем завершить текущий.

Кроме того, если моя активность A находится сверху, она имеет 2 действия (B, C) в фоновом стеке. Теперь, если активность A запущена в фоновом режиме и подключенном к USB-порту, только функция A будет правильно ее прослушивать? (У меня есть приемник usb, реализованный в каждом действии.)

Как я могу достичь этого без моего краха приложения?

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

Источник

finishAffinity() завершит эту деятельность, а также все действия сразу под ней в текущей задаче с одинаковой близостью

Если вы хотите, чтобы все уровни API
В одном из ваших действий

Затем в методе YourActivity onCreate () добавьте это, чтобы завершить действие

В приложении, которое я сделал, я поставил:

В каждом методе onResume () в каждом действии.

Globals – это класс, объявленный как манифест .xml. Класс Global имеет логическое имя exit.

Во всех меню опций действий включите параметр выхода, который устанавливает значение Globals.exit в true, и вызывает завершение ()

Затем все действия, оставшиеся незавершенными, закончены.

Не уверен, что вам нужно будет использовать намерение очистить заднюю часть, или если финиш очистит ее для вас. Извините, если я ошибаюсь в этом бите.

Извините за плохой ввод текста, я по телефону.

Источник

Оцените статью