Многооконный режим в Android N: что нужно знать разработчикам, чтобы извлечь из него максимальную пользу

Мы предоставляем обзор того, что будущая поддержка многооконности в Android N означает для разработчиков и как извлечь из нее максимальную пользу!

Поддержка нескольких окон — это замечательная функция, которую мы ждем в Android N, и мы давно хотели, чтобы он был доступен на всех устройствах. Однако, чтобы это было приятно, разработчикам, возможно, придется внести некоторые изменения в свои приложения для правильной поддержки.

Одна из сессий Google I/O была посвящена разработчикам, чтобы узнать о новых API и изменениях в поведении системы, которые приносит поддержка нескольких окон.

Сессию представил Вале Огунвале, ведущий технический менеджер Android ActivityManager и Компоненты платформы WindowManager — он и его команда отвечают за многооконный режим на Android.

Вы можете посмотреть Сеанс многооконного режима на YouTube, но мы также предоставляем здесь обзор сеанса.

N представляет три различных многооконных режима:
  • Режим разделенного экрана: этот режим доступен по умолчанию. Как следует из названия, он позволяет открывать два приложения одновременно.
  • Режим произвольной формы: производители могут включить его на более крупных устройствах, что позволяет пользователям свободно изменять размеры действий в дополнение к режиму разделенного экрана.
  • Режим «картинка в картинке»: предназначен для устройств Android TV. Этот режим предназначен для запуска видеоплееров в закрепленном окне, пока пользователь взаимодействует с другими приложениями.
Режим разделенного экрана Android NРежим Android N PiP
Стоит это отметить. мы уже рассматривали многооконность на N и высказали некоторую критику текущей системы. Имея это в виду, мы надеемся, что режим произвольной формы станет немного ближе к режиму «картинка в картинке», поскольку у него будут полезные приложения на всех устройствах.
Включить поддержку многооконности в ваших приложениях очень просто: вам не нужно ничего делать, если вы уже нацелились на N. Если вы решите отключить многооконность, вы можете сделать это, установив параметр. android: resizeableActivity атрибут активности в вашем манифесте. false. Это следует делать только в том случае, если это действительно оправдано, поскольку это всегда плохо выделяет ваше приложение. запуск в полноэкранном режиме, даже если пользователь (или другое приложение) пытается запустить его в многооконном режиме режим. Важно отметить, что атрибуты корневого действия применяются ко всем действиям в его стеке задач. Другими словами, если у вас есть действие, которое могут запускать другие приложения, убедитесь, что оно поддерживает многооконный режим. поскольку вы не можете гарантировать, что другие приложения запустят вашу активность в новой задаче, используя. Intent#FLAG_ACTIVITY_NEW_TASK .Поддержка режима «картинка в картинке» должна быть явно объявлена ​​через. android: supportsPictureInPicture атрибут. Обратите внимание, что этот атрибут игнорируется, если. android: resizeableActivity является. false Атрибуты .Layout можно использовать для установки размеров и размещения по умолчанию для окон произвольной формы или для указания минимальной ширины или высоты как для режимов произвольной формы, так и для режимов разделенного экрана:
  • android: defaultWidth/android: defaultHeight: размеры действия по умолчанию (режим произвольной формы).
  • android: gravity: исходное положение активности (режим произвольной формы).
  • android: minimalWidth/android: minimalHeight: минимальные размеры активности (режимы произвольной формы и разделенного экрана)
Пример кода вы можете найти в. Пример приложения Google Multi-Window Playground на Гитхабе: AndroidManifest.xml.
С появлением поддержки нескольких окон вам, возможно, придется дважды проверить некоторые вещи в своих приложениях, чтобы убедиться, что они работают правильно.

Понимание жизненного цикла активности

. жизненный цикл активности в многооконном режиме не изменяется: Базовый жизненный цикл активности Android При этом некоторые тонкие различия между состояниями активности могут привести к непреднамеренному поведению, которое вы обычно не замечали до появления N. Важно это знать. Activity#onResume() и. Activity#onPause() вызываются, когда ваше приложение получает или теряет фокус, но не обязательно, когда оно запускается или перестает быть видимым. (Помните, что только одно приложение может иметь фокус в любой момент времени.) Для приложений, которые постоянно обновляют контент (например, воспроизведение видео), обязательно обрабатывайте запуск и остановку обновлений контента. Activity#onStart() и. Activity#onStop() вместо. Например, если этого не делать для видеоприложений, будет означать, что воспроизведение произойдет только в том случае, если приложение сфокусировано, что противоречит цели многооконного режима. В официальном приложении YouTube возникла аналогичная проблема при первом запуске Android N Developer Preview..

Обработка изменений во время выполнения

Когда приложение переводится в многооконный режим, некоторые конфигурации устройства изменяются. Вы можете либо разрешить перезапуск вашей активности (в этом случае. сохранение фрагментов может быть хорошей идеей, если ваша деятельность должна выполнять интенсивную операцию при запуске) или по вашему выбору. явно обрабатывать изменения конфигурации вместо. При входе в многооконный режим или внутри него могут измениться четыре конфигурации устройства: screenSize, smallestScreenSize, screenLayout и. orientation. Обратитесь к. Документация для разработчиков Android для получения дополнительной информации о каждом атрибуте, но обратите на это внимание. orientation в данном случае больше не относится к ориентации устройства. Вместо этого он просто указывает, превышает ли ширина вашего действия его высоту (альбомную ориентацию) или нет (портрет). Заявить, что ваша деятельность будет обрабатывать эти изменения, можно из манифеста:
android: name=".MyActivity"android: configChanges="screenSize|smallestScreenSize|screenLayout|orientation"/>
Имейте в виду, что это означает, что вам действительно придется обрабатывать эти изменения. Activity#onConfigurationChanged(), вручную обновив представления или перезагрузив некоторые ресурсы.

Отключенные функции в многооконном режиме

Ваши действия в многооконном режиме не повлияют на некоторые функции системы:
  • Изменения в строке состояния и панели навигации, такие как затемнение/скрытие системных панелей или использование режима погружения, не будут иметь никакого эффекта. Это имеет смысл, поскольку ваша активность занимает только часть экрана.
  • android: screenOrientation Атрибут активности также не имеет никакого эффекта в многооконном режиме: поскольку размер вашей активности будет изменяться, для нее больше не имеет смысла иметь фиксированную ориентацию.
Были добавлены новые обратные вызовы для многооконных событий, а также методы запроса текущего состояния.
  • Activity#onMultiWindowModeChanged(boolean inMultiWindow): вызывается, когда состояние активности меняется с полноэкранного на многооконный и наоборот.
  • Activity#onPictureInPictureModeChanged(boolean inPictureOnPicture): вызывается, когда состояние активности меняется на режим PIP или обратно.
  • Activity#isInMultiWindowMode()/Activity#isInPictureInPictureMode(): возвращает информацию о том, находится ли действие в многооконном режиме/режиме «картинка в картинке» или нет.
  • Activity#overlayWithDecorCaption(boolean overlay): для окон произвольной формы этот метод можно использовать, чтобы заголовок (полоса, используемая для перетаскивания окна) накладывался на содержимое, а не сдвигал его вниз.
ПС. За исключением. Activity#overlayWithDecorCaption(), эти методы также предоставляются. Fragment сорт.

Запуск действий в многооконном режиме

  • Activity#enterPictureInPictureMode() можно использовать для перевода действия в режим «картинка в картинке». Обратите внимание, что действия в режиме PiP не получают уведомления о событиях ввода — используйте MediaSession#setMediaButtonReceiver() если вы хотите обрабатывать такие события. Также обязательно посетите веб-сайт разработчиков Android, если вас интересует Картинка в картинке на Android N.
  • Если устройство находится в режиме разделенного экрана, вы можете указать системе запустить другое действие рядом с вашим, используя Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT флаг. Флаг не имеет никакого эффекта, если не в режиме разделенного экрана.
  • Если устройство находится в режиме произвольной формы, ActivityOptions#setLaunchBounds() можно использовать для указания размеров и местоположения нового действия на экране.
Примеры кода см. в образце приложения Multi-Window Playground: пример смежной деятельности, пример границ запуска.

Перетащите

Хотя поддержка перетаскивания существовала со времен Honeycomb, раньше это было возможно только в рамках одного и того же действия. Это снег. поддерживается в многооконном режиме также. Реализация этого, кажется, есть. в основном то же самое, что и раньше, с несколькими дополнениями для перетаскивания между действиями:
  • View#startDragAndDrop()
    • Новый псевдоним для View#startDrag().
    • Чтобы включить перетаскивание перекрестной активности, передайте новый флаг View#DRAG_FLAG_GLOBAL.
    • Если вам нужно предоставить разрешения URI для активности получателя, передайте новые флаги. View#DRAG_FLAG_GLOBAL_URI_READ или View#DRAG_FLAG_GLOBAL_URI_WRITE, по мере необходимости.
  • View#updateDragShadow()
    • Заменяет тень для операции перетаскивания, выполняемой в данный момент. Может вызываться только приложением, инициировавшим операцию перетаскивания.
  • View#cancelDragAndDrop()
    • Отменяет операцию перетаскивания, выполняющуюся в данный момент. Может вызываться только приложением, инициировавшим операцию перетаскивания.
  • Проверить, поддерживает ли устройство режимы произвольной формы или «картинка в картинке», можно через PackageManager#hasSystemFeature(), с использованием PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT и PackageManager#FEATURE_FREEFORM_PICTURE_IN_PICTURE соответственно.
  • android: windowBackground Атрибут можно использовать в качестве фонового изображения, если размер действия изменяется и его рендеринг отстает. Если android: windowBackground не установлен, android: windowBackgroundFallback вместо этого используется. Пример см. в образце приложения Multi-Window Playground..
Уэйл предложил несколько лучших практик, которые помогут вашим пользователям получить наилучшие впечатления:
  • Режим обработки меняется элегантно:
    • Поддерживать согласованность пользовательского интерфейса независимо от ориентации. Не допускайте изменения положения элементов, чтобы обеспечить плавные переходы.
    • Развивая вышеизложенное, не переключайтесь между очень разными макетами для макетов телефона/планшета. Вместо этого адаптируйте макет планшета для меньших размеров для обеспечения единообразия.
  • Убедитесь, что ваша деятельность адаптирована к небольшим размерам к следуя шаблонам Material Design.
  • Использовать FLAG_ACTIVITY_LAUNCH_ADJACENT когда имеет смысл сделать работу в режиме разделенного экрана более приятной.
  • Объявляйте о несовместимости изменения размера только тогда, когда это оправдано.. Как мы обсуждали выше, в противном случае ваше приложение будет плохо выделяться.
Уэйл завершил сессию, предложив несколько дополнительных полезных ресурсов:
  • Многооконная документация.
  • Рекомендации по Material Design для режима разделенного экрана.
  • Пример многооконного приложения.