Как исправить приложение перейти в фоновый режим после переупорядочения вперед и назад - PullRequest
0 голосов
/ 13 декабря 2018

В настоящее время мне удалось разрешить пользователю переключаться между двумя различными группами действий (скажем, 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 'onPause() и isFinishing() и startActivty() B, но он всегда будет вызывать B onCreate() даже при использовании FLAG_ACTIVITY_REORDER_TO_FRONT, что заставляет меня думать, что это неправильное решение.Правильное решение должно выяснить, как предотвратить скрытие приложения в фоновом режиме.

1 Ответ

0 голосов
/ 25 декабря 2018

Я неправильно понимаю флаг FLAG_ACTIVITY_REORDER_TO_FRONT.Я думал, что активность Y FLAG_ACTIVITY_REORDER_TO_FRONT активность C сохранит родительский элемент, поэтому обратное нажатие C перейдет к 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.

Если задача вкладки уже запущена ранее, допустимые флаги равны loop , чтобы переупорядочить все те же действия задачи (сохранить в глобальном списке стека)являются (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);это создает новую деятельность на вершине того же класса.Но не делайте этого, когда A запускает действие B, поскольку 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 в одном из действий в манифесте.

...