Хорошо, давайте посмотрим на это согласно последовательности операций.
откройте приложение, отображается основное действие
Состояние backstack: Main Activity (root)
выйти из приложения с помощью кнопки «назад», чтобы не выполнять никаких действий
Состояние backstack: <No activity present as back was pressed>
принятьтрансляция, которая запускает новое действие A (флаг new_task)
Статус backstack: ActivityA (root)
открыть действие B, нажав на кнопку в действии A (нетфлаги)
Статус backstack: ActivityA (root) -> ActivityB (top)
принять трансляцию, которая начинает новое действие A (флаг new_task)
Статус backstack:ActivityA (root) -> ActivityB (top)
Здесь Actvitity A не запускается, потому что он был запущен с флагом намерения 'FLAG_ACTIVITY_NEW_TASK', который имеет следующую документацию:
При использовании этого флага, если задача уже запущена для действия, которое вы сейчас запускаете, тогда новое действие будетне начнется;вместо этого текущее задание будет просто выведено на переднюю часть экрана в том состоянии, в котором оно было последним.
новое действие A не запускается (если я вернусь, все еще есть предыдущее действие A)
На шаге № 6 должно быть представлено действие A, но это не так.
Таким образом, текущая задача выглядит следующим образом ActivityA (root) -> ActivityB(top)
, ActivityA
уже присутствует в задаче, и поэтому задача в целом только что выведена на фронт , чтоозначает, что ActivityB
все еще находится наверху задачи.
Если я попытаюсь вместо этого представить действие C (в # 5), оно будет отображаться, как и ожидалось.
ActivityC
- это новое действие, которого нет в задании, поэтому оно создано для вас.
Если в # 2 я покидаю приложение,Вместо кнопки homebutton все работает, как и ожидалось.
В прессе homebutton главное то, что в этом случае MainActivity не разрушается, а просто отодвигается на задний план.
Итак, после # 2ваш статус backstack будет выглядеть все еще с экземпляром MainActivity в качестве корня, например:
Main Activity (root)
Теперь, до # 5, backstack будет выглядеть следующим образом:
Main Activity (root) -> ActivityA -> ActivityB (top)
После # 5 ваш backstack выглядит так:
Main Activity (root) -> ActivityA -> ActivityB -> ActivityA (top)
Я полагаю, что причина этого в том, что MainActivity
запускается по умолчанию с флагами намерений:
FLAG_ACTIVITY_NEW_TASK |FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
Это также запускает повторное создание задачи, и поэтому оно имеет контроль над новыми действиями, созданными с новым флагом задачи (с той же привязкой, что и у родительского приложения), и тем, как оно может переместить такую деятельность в своюзадача.
Более подробную информацию об этом можно найти здесь
И как я могу гарантировать, что действие всегда представлено?Я мог бы использовать FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP, но я хочу сохранить backstack.
Поскольку это структура данных стека , вы не можете изменить порядок своей деятельности, однако вы можете исправить это, добавивфлаг: FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
в получателе, который создает ActivityA, поскольку это обеспечит создание нового экземпляра / задачи для действия независимо от того, присутствовало ли оно уже или нет.(Не рекомендуемое решение - но работает)
Но если вы хотите сохранить тот же экземпляр ActivityA
, вам придется добавить параметр taskAffinity к вашей деятельности в манифесте.
<activity android:name=".ActivityB" android:taskAffinity="com.example.pendingintent"></activity>
<activity android:name=".ActivityA" android:taskAffinity="com.example.abctest" />
, а затем начните обе свои действия A и B с флагом new_task
Здесь - это отличное слайд-шоу, объясняющее taskAffinity и как оно влияет на создание действий.