Как исправить приложение перейти в фоновый режим после переупорядочения вперед и назад
В настоящее время мне удалось разрешить пользователю переключаться между двумя различными группами действий (скажем, 4 класса активности A/B группа и группа X/Y) и переключаться с помощью FLAG_ACTIVITY_REORDER_TO_FRONT
флаг, но я заметил странное поведение:
A ->(start activity) X
X ->(reorder to front) A
X , A ->(start) B ->(start) B2
A , B , B2 ->(reorder to front) X ->(start) Y
X , Y ->(reorder to front) A , B , B2
X , Y , A , B <-(press back, app hide to background, B2 destroyed) B2
X , Y , A , B (click to foreground, B is here just fine)
Как предотвратить скрытие приложения в фоновом режиме B2
?
Я заметил, что это происходит только в одном классе (B
а также B2
это тот же класс), если я использую B
а также C
, это не будет такой проблемой, я хотел бы знать, в чем причина.
А также X ->(start) Y
также ключ к его воспроизведению.
Я пытался использовать пользовательский список экземпляров уровня приложения для обнаружения B2
"s onPause()
а также isFinishing()
а также startActivty()
B
, но он всегда звонит B
"s onCreate()
хотя с использованием FLAG_ACTIVITY_REORDER_TO_FRONT
что заставляет меня думать, что это не правильное решение. Правильное решение должно выяснить, как предотвратить скрытие приложения в фоновом режиме.
1 ответ
Я неправильно понимаю FLAG_ACTIVITY_REORDER_TO_FRONT
флаг. Я думал, что деятельность Y FLAG_ACTIVITY_REORDER_TO_FRONT
активность C сохранит родителя, поэтому C backpress перейдет к B. Нет, это не так. FLAG_ACTIVITY_REORDER_TO_FRONT
фактически делает передачу C новому родителю Y (то есть вызывающему), но так как родитель Y находится над C, то обратное нажатие C не сможет перейти в Y и сворачиваться / скрываться от фона.
Я также неправильно понимаю мой код создания 2 стека, но на самом деле это всего лишь один стек. Я должен использовать FLAG_ACTIVITY_MULTIPLE_TASK
чтобы сделать это несколько стеков.
Мне также нужно определить правильный launchMode
в декларации:
- Обе активности запуска A и X должны быть определены как
singleInstance
в манифесте. - Обе операции домашней страницы B и Y должны быть определены как
singleTop
в манифесте. - Другие действия C и Z ... и т. Д. Должны быть определены как
singleTask
в манифесте.
Деятельность A должна установить флаг Intent.FLAG_ACTIVITY_MULTIPLE_TASK
когда начать домашнюю страницу B.
X также должен установить флаг Intent.FLAG_ACTIVITY_MULTIPLE_TASK
когда стартует домашняя страница Y.
Если задача вкладки уже была запущена ранее, допустимыми флагами для циклического переупорядочения всех одинаковых действий задачи (сохранения в глобальном списке стека) являютсяmoveTaskToBack(true);
одиночная строка также работает, но она не может вернуться на передний план):
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|Intent.FLAG_ACTIVITY_NEW_TASK
|Intent.FLAG_ACTIVITY_NO_ANIMATION);
p / s: вышеописанное не будет работать в Android 5 и 6, которые будут переупорядочивать только одну верхнюю активность, поэтому мне нужно добавить android.permission.REORDER_TASKS
в манифесте и сделайте это (подробнее, см. отчет об ошибке):
ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (final Activity a : YStackClasses) {
if (IsBeforeAndroidNougat && (tasksManager != null)) {
tasksManager.moveTaskToFront(a.getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION);
} else {
//Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
}
}
Если задача вкладки никогда не запускалась, следует запустить активность запуска без установки какого-либо специального флага.
Для предотвращения нажатия кнопки запуска обновится из-за singleInstance
Я также должен сделать проверку в A и B, поставить его перед setContentView
а также finish()
/return;
рано.
if (getIntent() != null && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
//figure out latest activity and it's home activity, and reorder to front, and its entire task stack will focus on top.
}
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
больше не будет автоматически очищать все действия, чтобы обновить приложение, решение ActivityCompat.finishAffinity(desiredTask's Top Act);
, который удалит все активы из верхней части активности, не влияя на стек других задач.
Если класс повторного использования, например, C1, C2, то я должен использовать startActivityForResult(intent, dummyResponse);
заставить его создать новую деятельность на вершине того же класса. Но не делайте этого, когда А начинает деятельность с startActivityForResult
требует одной задачи и игнорировать singleInstance
launchMode, смотрите эту ветку. И не делай ForResult
внутри onNewIntent()
что может привести к тому, что страница будет сгенерирована дважды в стеке (вторая страница генерируется не сразу, а только после возвращения). Но я могу сделать ForResult
в вызывающей onNewIntent()
вступить в силу.
Мне также нужно сделать это, чтобы заставить работать спину должным образом в домашних условиях, чтобы скрыть приложение и вернуться на нужную страницу задач. Я не пользуюсь TASK_ON_HOME
(при запуске домашней страницы B класса) помечают, потому что это только одно направление задачи (т. е. приоритет перед фиксированной активностью, а не зависит от предыдущей главной задачи):
@Override //B class
public void onBackPressed() {
moveTaskToBack(true); //B task stack
if (YStackClasses.size() > 0) { //Y task stack
try {
YStackClasses.get(0).moveTaskToBack(true);
} catch (Exception e) {
e.printStackTrace();
}
}
super.onBackPressed();
}
И будьте осторожны, стек приложений может кешироваться, даже несмотря на то, что он перезапускается автоматически из-за сбоя, поэтому иногда вам нужно выполнить повторный запуск дважды, чтобы вернуться в исходное состояние стека для тестирования, иначе вы получите неправильный вывод.
Вот и все, в этом ответе может не быть подробностей кода, но он должен помочь, если вы столкнетесь с такой же проблемой "скрыть фон при повторном нажатии", как я, вы можете понять, насколько сложно добиться ожидаемого поведения, если вы установили неправильный флаг за один шаг или определен неправильно launchMode
в одном из действий в манифесте.