В Android 9 (и более ранних версиях) приложения переводились в состояние PAUSED когда:
- Новая полупрозрачная активность, запущенная поверх приложения, когда приложение все еще было видно (и, следовательно, не было остановлено).
- Активность потеряла фокус, но не была скрыта, и пользователь мог взаимодействовать с ней. Например, в многооконном режиме несколько действий могут быть видны и одновременно принимать сенсорный ввод.
Эти ситуации различаются количеством приостановок , которое должно выполнять приложение, но их нельзя различить на уровне приложения.
В Android 10 все основные действия в видимых стеках находятся в состоянии RESUMED . Это улучшает совместимость с режимами Multi-Window и MD для приложений, которые используют onPause() вместо onStop() , чтобы прекратить обновление пользовательского интерфейса и взаимодействие с пользователем. Это означает:
- Оба действия в разделенном экране возобновляются.
- Возобновляются все самые видимые действия в свободном оконном режиме.
- Действия на нескольких экранах могут быть возобновлены одновременно.

Рисунок 1. Мультирезюме на складном устройстве

Рисунок 2. Мультирезюме в режиме рабочего стола
Действия могут находиться в состоянии PAUSED когда на них нельзя сфокусироваться или они частично закрыты, например:
- В свернутом разделенном экране (с панелью запуска сбоку) верхняя активность не возобновляется, потому что на нее нельзя сфокусироваться.
- В режиме «картинка в картинке» действие не возобновляется, потому что на него нельзя сфокусироваться.
- Когда действия покрываются другими прозрачными действиями в том же стеке.
Этот подход указывает приложениям, что действие может получать ввод от пользователя только в состоянии RESUMED . До Android 10 действия также могли получать входные данные в состоянии PAUSED (например, попробуйте одновременно коснуться обоих действий в режиме разделенного экрана на устройстве под управлением Android 9).
Чтобы сохранить возобновленный сигнал из предыдущих выпусков Android (и сообщить, когда приложения должны получить доступ к монопольным или одноэлементным ресурсам), Android 10 включает новый обратный вызов:
Activity#onTopResumedActivityChanged(boolean onTop)
При вызове этот обратный вызов вызывается между Activity#onResume() и Activity#onPause() . Этот обратный вызов является необязательным и может быть пропущен, поэтому действие может перейти из состояния RESUMED в состояние PAUSED , не становясь самым верхним в системе. Например, в многооконном режиме. Поскольку этот обратный вызов является необязательным, он не является частью жизненного цикла действия и должен использоваться редко.
Предыдущее действие с возобновлением наверху получает и завершает выполнение onTopResumedActivity(false) до того, как следующее действие с возобновлением наверху получит onTopResumedActivity(true) , если предыдущее действие не занимает слишком много времени для обработки вызова метода и не достигает тайм-аута 500 мс.
Совместимость
Чтобы обеспечить совместимость при реализации нескольких резюме, рассмотрите эти решения.
Несколько возобновленных действий в одном процессе приложения
- Проблема. В Android 9 и ниже одновременно возобновляется только одно действие в системе. Все переходы между действиями предполагают приостановку действия перед возобновлением другого. Некоторые приложения и фреймворки (такие как Flutter или Android LocalActivityManager) используют этот факт и сохраняют состояние возобновленной активности в синглтонах.
- Решение. В Android 9 и более ранних версиях, если возобновляются два действия из одного и того же процесса, система возобновляет только действие с более высоким Z-порядком. Приложения, ориентированные на Android 10, могут поддерживать одновременное возобновление нескольких действий.
Одновременный доступ к камере
- Проблемы . Эти проблемы также присутствуют в Android 9 и более ранних версиях. Например, полноэкранное и возобновленное действие может переключить фокус камеры на приостановленное действие вверху в режиме «картинка в картинке», но стать более заметным при более широком внедрении многооконного и многоэкранного режимов.
- Из-за изменений, внесенных в состояние
RESUME, приложения могут быть отключены от камеры даже во время возобновления работы. Чтобы решить эту проблему, приложения должны обрабатывать отключение камеры без сбоев. При отключении приложения получают обратный вызов отключения, и все вызовы в API начинаютCameraAccessException. -
resizeableActivity=falseне является гарантией эксклюзивного доступа к камере, поскольку другие приложения, использующие камеру, могут быть открыты на других дисплеях.
- Из-за изменений, внесенных в состояние
- Решения. Разработчики должны включить логику, когда приложение отключается от камеры. Если приложение отключено от камеры, оно должно отслеживать обратные вызовы доступности камеры, чтобы попытаться повторно подключиться и продолжить использование камеры. В дополнение к существующему
CameraManager#AvailabilityCallback#onCameraAvailable()в Android 10 добавленCameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged(), который охватывает случай, когда фокус (и приоритет камеры) переключается между несколькими возобновленными действиями. Разработчики приложений должны использовать оба этих обратных вызова, чтобы определить подходящее время для попытки получить доступ к камере.
Мульти-резюме
В Android 10 состояние жизненного цикла активности определяется видимостью и Z-порядком. Чтобы убедиться, что правильное состояние после обновления видимости для действия и оценить, какое состояние жизненного цикла применимо, вызовите метод ActivityRecord#makeActiveIfNeeded() из разных мест. В Android 10 активный означает RESUMED или PAUSED и работает только в этих двух случаях.
В Android 10 возобновление действия отслеживается отдельно в каждом стеке, а не в одном месте в системе. Это связано с тем, что несколько переходов активности могут выполняться одновременно в многооконных режимах. Дополнительные сведения см. в разделе ActivityStack#mInResumeTopActivity .
Обратный вызов по возобновленной активности
После действий, которые могут привести к изменению основного действия (например, запуск, возобновление действия или изменение Z-порядка), ActivityStackSupervisor#updateTopResumedActivityIfNeeded() . Этот метод проверяет, изменилась ли самая верхняя возобновленная активность, и при необходимости выполняет обновление. Если предыдущее действие с возобновлением наибольшей активности не освободило состояние возобновления наибольшей активности, то ему отправляется сообщение о потере состояния наибольшей возобновленной активности, а на стороне сервера планируется тайм-аут ( ActivityStackSupervisor#scheduleTopResumedStateLossTimeout() ). Отчет о состоянии верхнего возобновления отправляется следующему действию после того, как предыдущее освободило состояние или когда истекло время ожидания (см. Использование:
ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()
Был добавлен новый элемент транзакции TopResumedActivityChangeItem , чтобы сообщать клиентам об изменениях состояния, возобновленных в верхней части, и использует архитектуру ActivityLifecycler из Android 9.
Верхнее возобновленное состояние сохраняется на стороне клиента, и каждый раз, когда действие переходит в RESUMED или PAUSED , оно также проверяет, следует ли вызывать обратный вызов onTopResumedActivityChanged() . Это обеспечивает определенную развязку в обмене состояниями жизненного цикла и состоянием верхнего возобновления между серверной и клиентской сторонами.