1page.title=Поддержка многооконного режима 2page.metaDescription=Новые возможности в Android N для одновременного отображения нескольких приложений. 3page.keywords="multi-window", "android N", "split screen", "free-form" 4 5@jd:body 6 7<div id="qv-wrapper"> 8 <div id="qv"> 9 <h2>Содержание документа</h2> 10 <ol> 11 <li><a href="#overview">Обзор</a></li> 12 <li><a href="#lifecycle">Жизненный цикл многооконного режима</a></li> 13 <li><a href="#configuring">Настройка приложения для многооконного 14 режима</a></li> 15 <li><a href="#running">Запуск приложения в многооконном режиме</a></li> 16 <li><a href="#testing">Тестирование приложения в многооконном режиме</a></li> 17 </ol> 18 <h2>См. также:</h2> 19 <ol> 20 <li><a class="external-link" href="https://github.com/googlesamples/android-MultiWindowPlayground">Пример 21 многооконного демонстрационного приложения</a></li> 22 </ol> 23 </div> 24</div> 25 26<p> 27 В Android N добавлена поддержка отображения нескольких приложений 28 одновременно. На мобильных устройствах два приложения могут быть запущены рядом 29 или друг над другом в режиме <em>разделения экрана</em>. На телевизорах приложения могут 30 использовать режим <em>"картинка в картинке"</em>, чтобы воспроизводить видео, 31 пока пользователи работают с другим приложением. 32</p> 33 34<p> 35 Если вы создаете приложение с использованием N Preview SDK, вы можете указать, как оно 36 будет действовать в многооконном режиме. Например, можно задать минимальные 37 допустимые размеры окна приложения. Также можно отключить многооконный режим для приложения, 38 чтобы оно отображалось только в полноэкранном 39 режиме. 40</p> 41 42<h2 id="overview">Обзор</h2> 43 44<p> 45 В Android N несколько приложений могут одновременно находиться на экране. Например, 46 пользователь может разделить экран, чтобы просматривать веб-страницу 47 слева и писать сообщение электронной почты справа. Возможности пользователя зависят от 48 устройства. 49</p> 50 51<ul> 52 <li>На мобильных устройствах с Android N доступен режим 53 разделения экрана. В этом режиме два приложения отображаются рядом 54 или друг над другом. Пользователь может перетащить 55 линию разделения, чтобы увеличить окно одного приложения и уменьшить окно другого. 56 </li> 57 58 <li>На устройствах Nexus Player с Android N для приложений 59 будет доступен <a href="picture-in-picture.html">режим "картинка в картинке"</a>, который 60 позволит приложению отображать контент, пока пользователь просматривает 61 другие приложения или взаимодействует с ними. 62 </li> 63 64 <li>Производители более крупных устройств могут активировать 65 режим произвольной формы, где пользователь может любым образом изменять размер каждого окна. В этом случае 66 помимо режима разделения экрана 67 на устройстве будет доступен и этот режим. 68 </li> 69</ul> 70 71<img src="{@docRoot}preview/images/mw-splitscreen.png" alt="" width="650" srcset="{@docRoot}preview/images/mw-splitscreen.png 1x, 72 {@docRoot}preview/images/mw-splitscreen_2x.png 2x," id="img-split-screen" /> 73<p class="img-caption"> 74 <strong>Рис. 1.</strong> Два приложения отображаются рядом в режиме разделения экрана. 75</p> 76 77<p> 78 Пользователь может перейти в многооконный режим следующими способами. 79</p> 80 81<ul> 82 <li>Если пользователь откроет <a href="{@docRoot}guide/components/recents.html">экран 83 обзора</a> и длительно нажмет 84 название операции, ее можно будет перетащить в выделенную часть 85 экрана и переключить в многооконный режим. 86 </li> 87 88 <li>Если пользователь длительно нажмет кнопку "Обзор", устройство 89 переключит текущую операцию в многооконный режим и откроет экран обзора, 90 где пользователь сможет выбрать другую операцию для совместного отображения. 91 </li> 92</ul> 93 94<p> 95 Пользователи могут <a href="{@docRoot}guide/topics/ui/drag-drop.html">перетаскивать</a> 96данные между окнами операций в режиме 97 совместного отображения. (Ранее перетаскивать данные можно было только в рамках 98 одной операции). 99</p> 100 101<h2 id="lifecycle">Жизненный цикл многооконного режима</h2> 102 103<p> 104 Многооконный режим не меняет <a href="{@docRoot}training/basics/activity-lifecycle/index.html">жизненный 105 цикл операции</a>. 106</p> 107 108<p> 109 В этом режиме в каждый момент времени активной 110 является только последняя операция, с которой взаимодействовал пользователь. Такая операция считается <em>самой верхней</em>. 111 Все другие операции приостановлены, даже если они отображаются. 112 Однако система отдает приостановленным, но видимым операциям более 113 высокий приоритет, чем невидимым. Если пользователь взаимодействует с 114 одной из приостановленных операций, она возобновляется, а прежняя самая верхняя 115 операция приостанавливается. 116</p> 117 118<p class="note"> 119 <strong>Примечание.</strong> В многооконном режиме приложение может быть приостановлено 120 и по-прежнему видимо для пользователя. Приложению может потребоваться 121 продолжать свои операции, даже если оно приостановлено. Например, видимое приостановленное приложение, 122 воспроизводящее видео, будет по-прежнему показывать видео. Поэтому 123 мы <em>не</em> рекомендуем приостанавливать воспроизведение 124 в обработчиках {@link android.app.Activity#onPause onPause()} таких приложений. 125 Вместо этого следует приостановить видео в {@link android.app.Activity#onStop 126 onStop()} и возобновить воспроизведение в {@link android.app.Activity#onStart 127 onStart()}. 128</p> 129 130<p> 131 Если пользователь переводит приложение в многооконный режим, система 132 уведомляет операцию об изменении конфигурации, как указано в документе <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Обработка изменений 133 во время выполнения</a>. По сути это изменение так же действует 134на жизненный цикл операции, как уведомление приложения системой 135о переходе устройства из вертикальной ориентации в 136 горизонтальную, только изменяются размеры экрана, а не ориентация. Как описано в документе <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Обработка изменений 137 во время выполнения</a>, операция может обработать изменение 138 конфигурации самостоятельно или может позволить системе 139 удалить окно операции и создать его заново с новыми размерами. 140</p> 141 142<p> 143 Если пользователь увеличивает одну из сторон окна, система меняет 144 размер окна операции в соответствии с действием пользователя и применяет <a href="{@docRoot}guide/topics/resources/runtime-changes.html">изменения в режиме выполнения</a> 145 по мере необходимости. Если приложение не успевает отрисовать новые области, система 146 временно заполняет их цветом, заданным атрибутом {@link 147 android.R.attr#windowBackground windowBackground} или атрибутом стиля 148 <code>windowBackgroundFallback</code> по умолчанию. 149</p> 150 151<h2 id="configuring">Настройка приложения для многооконного режима</h2> 152 153<p> 154 Если ваше приложение предназначено для Android N, вы 155 можете указать, каким образом поддерживают (и поддерживают ли) операции вашего приложения многооконный режим. Атрибуты управления размером и макетом устанавливаются 156 в манифесте. 157 Настройки атрибутов корневой операции применяются 158 ко всем операциям в ее стеке задач. 159</p> 160 161<p class="note"> 162 <strong>Примечание.</strong> Если приложение с поддержкой различной 163 ориентации было создано с версией SDK, 164 более ранней, чем Android N, и пользователь запустит это приложение в многооконном режиме, система принудительно изменит размер приложения. Система отображает диалоговое окно 165 с предупреждением о том, что приложение может работать непредвиденным образом. Система 166 <em>не</em> меняет размер окна для приложений с 167 фиксированной ориентацией. Если пользователь попытается открыть такое приложение 168 в многооконном режиме, оно займет весь экран. 169</p> 170 171<h4 id="resizeableActivity">android:resizeableActivity</h4> 172<p> 173 Установите этот атрибут в узле <code><activity></code> или 174 <code><application></code> манифеста, чтобы включить или отключить многооконный 175 режим: 176</p> 177 178<pre> 179android:resizeableActivity=["true" | "false"] 180</pre> 181 182<p> 183 Если для этого атрибута задано значение true, операцию можно запускать 184 в режимах разделения экрана и произвольной формы. Если для атрибута задано значение false, 185 операция не поддерживает многооконный режим. Если значение равно false и 186 пользователь пытается запустить операцию в многооконном режиме, она 187 занимает весь экран. 188</p> 189 190<p> 191 Если приложение предназначено для Android N, но 192значение для этого атрибута не было указано, то по умолчанию используется значение true. 193</p> 194 195<h4 id="supportsPictureInPicture">android:supportsPictureInPicture</h4> 196 197<p> 198 Установите этот атрибут в узле <code><activity></code> манифеста, 199 чтобы указать, поддерживает ли операция режим "картинка в картинке". Этот 200 атрибут не принимается во внимание, если для <code>android:resizeableActivity</code> установлено значение false. 201</p> 202 203<pre> 204android:supportsPictureInPicture=["true" | "false"] 205</pre> 206 207<h3 id="layout">Атрибуты макета</h3> 208 209<p> 210 В Android N элемент манифеста <code><layout></code> поддерживает 211 несколько атрибутов, которые определяют поведение 212 операции в многооконном режиме. 213</p> 214 215<dl> 216 <dt> 217 <code>android:defaultWidth</code> 218 </dt> 219 220 <dd> 221 Ширина окна операции по умолчанию в режиме произвольной формы. 222 </dd> 223 224 <dt> 225 <code>android:defaultHeight</code> 226 </dt> 227 228 <dd> 229 Высота окна операции по умолчанию в режиме произвольной формы. 230 </dd> 231 232 <dt> 233 <code>android:gravity</code> 234 </dt> 235 236 <dd> 237 Начальная позиция окна операции в режиме произвольной формы. Допустимые значения 238 см. в описании класса {@link android.view.Gravity}. 239 </dd> 240 241 <dt> 242 <code>android:minimalSize</code> 243 </dt> 244 245 <dd> 246 Минимальные значения высоты и ширины окна операции в режимах разделения экрана 247 и произвольной формы. Если пользователь перемещает разделительную линию 248 в режиме разделения экрана, чтобы сделать размер окна операции 249 меньше указанного минимума, система обрезает его до запрошенного пользователем размера. 250 </dd> 251</dl> 252 253<p> 254 В следующем примере кода показано, как задать размер и 255 позицию окна операции по умолчанию, а также ее минимальный размер в 256 режиме произвольной формы: 257</p> 258 259<pre> 260<activity android:name=".MyActivity"> 261 <layout android:defaultHeight="500dp" 262 android:defaultWidth="600dp" 263 android:gravity="top|end" 264 android:minimalSize="450dp" /> 265</activity> 266</pre> 267 268<h2 id="running">Запуск приложения в многооконном режиме</h2> 269 270<p> 271 Android N предоставляет новые возможности для поддержки 272 приложений в многооконном режиме. 273</p> 274 275<h3 id="disabled-features">Недоступные возможности в многооконном режиме</h3> 276 277<p> 278 Некоторые возможности отключены или игнорируются в многооконном 279 режиме, потому что они не имеют смысла для операции, которая отображается 280 на экране устройства одновременно с другими операциями или приложениями. Ниже приведены примеры таких возможностей. 281 282<ul> 283 <li>Отключены некоторые параметры настройки <a href="{@docRoot}training/system-ui/index.html">системного интерфейса</a>. 284 Например, приложения не могут 285 скрыть строку состояния, если они не работают в полноэкранном режиме. 286 </li> 287 288 <li>Система не учитывает изменения атрибута <code><a href= 289 "{@docRoot}guide/topics/manifest/activity-element.html#screen" 290 >android:screenOrientation</a></code>. 291 </li> 292</ul> 293 294<h3 id="change-notification">Уведомления об изменениях и запросы в многооконном режиме</h3> 295 296<p> 297 Для поддержки многооконного режима в класс {@link android.app.Activity} 298 были добавлены следующие методы. Подробнее о каждом из них см. в 299 <a href="{@docRoot}preview/setup-sdk.html#docs-dl">справочнике по N Preview SDK</a>. 300</p> 301 302<dl> 303 <dt> 304 <code>Activity.inMultiWindow()</code> 305 </dt> 306 307 <dd> 308 Вызовите этот метод, чтобы узнать, находится ли операция в многооконном режиме. 309 </dd> 310 311 <dt> 312 <code>Activity.inPictureInPicture()</code> 313 </dt> 314 315 <dd> 316 Вызовите этот метод, чтобы узнать, находится ли операция в режиме "картинка в картинке". 317 318 <p class="note"> 319 <strong>Примечание.</strong> Режим "картинка в картинке" — это частный 320 случай многооконного режима. Если метод <code>myActivity.inPictureInPicture()</code> 321 возвращает значение true, <code>myActivity.inMultiWindow()</code> также возвращает 322 true. 323 </p> 324 </dd> 325 326 <dt> 327 <code>Activity.onMultiWindowChanged()</code> 328 </dt> 329 330 <dd> 331 Система вызывает этот метод, когда операция переходит в многооконный 332 режим или выходит из него. Система передает методу значение true, если 333 операция входит в многооконный режим, и значение false, если 334 она выходит из него. 335 </dd> 336 337 <dt> 338 <code>Activity.onPictureInPictureChanged()</code> 339 </dt> 340 341 <dd> 342 Система вызывает этот метод, когда операция переходит в режим 343 "картинка в картинке". Система передает методу значение true, 344 если операция входит в режим "картинка в картинке", и значение false, 345 если она выходит из него. 346 </dd> 347</dl> 348 349<p> 350 Также существуют версии {@link android.app.Fragment} для этих методов, 351например, <code>Fragment.inMultiWindow()</code>. 352</p> 353 354<h3 id="entering-pip">Переход в режим "картинка в картинке"</h3> 355 356<p> 357 Чтобы перевести операцию в режим "картинка в картинке", 358 вызовите новый метод <code>Activity.enterPictureInPicture()</code>. Этот метод игнорируется, если 359 устройство не поддерживает режим "картинка в картинке". Дополнительная информация содержится в документации 360 <a href="picture-in-picture.html">Режим "картинка в картинке"</a>. 361</p> 362 363<h3 id="launch">Запуск новых операций в многооконном режиме</h3> 364 365<p> 366 При запуске новой операции можно сообщить системе, что окно новой 367 операции следует показать рядом с текущим, если это возможно. Для этого 368 используйте флаг 369 <code>Intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT</code>. Этот 370 флаг запрашивает следующее поведение. 371</p> 372 373<ul> 374 <li>Если устройство находится в режиме разделения экрана, система пытается 375 создать окно новой операции рядом с окном запустившей ее операции, 376 чтобы разместить две операции на экране. Не гарантируется, что система сможет это сделать, но если 377 это возможно, операции отображаются рядом друг с другом. 378 </li> 379 380 <li>Если устройство не находится в режиме разделения экрана, этот флаг не учитывается. 381 </li> 382</ul> 383 384<p> 385 Если при запуске 386 новой операции устройство находится в режиме произвольной формы, вы можете задать размеры и позицию окна новой операции, 387 вызвав метод <code>ActivityOptions.setLaunchBounds()</code>. Этот метод игнорируется, если 388 устройство не находится в многооконном режиме. 389</p> 390 391<p class="note"> 392 <strong>Примечание.</strong> Если запустить операцию в стеке задач, 393 она заменит операцию на экране, унаследовав все ее 394 свойства многооконного режима. Чтобы запустить новую операцию в отдельном 395 окне в многооконном режиме, ее следует запустить в новом стеке задач. 396</p> 397 398<h3 id="dnd">Поддержка перетаскивания</h3> 399 400<p> 401 Пользователи могут <a href="{@docRoot}guide/topics/ui/drag-drop.html">перетаскивать</a> данные 402 между окнами операций в режиме 403 совместного отображения. (Ранее перетаскивать данные можно было только в рамках 404 одной операции). Поэтому вы можете реализовать функции перетаскивания 405 в своем приложении, если оно еще их не поддерживает. 406</p> 407 408<p> 409 В N Preview SDK пакет <a href="{@docRoot}reference/android/view/package-summary.html"><code>android.view</code></a> 410 расширен для поддержки перетаскивания между приложениями. Дополнительная информация о нижеприведенных классах 411 и методах содержится в <a href="{@docRoot}preview/setup-sdk.html#docs-dl">справочнике по N 412 Preview SDK</a>. 413</p> 414 415<dl> 416 <dt> 417 <code>android.view.DropPermissions</code> 418 </dt> 419 420 <dd> 421 Объект токена для указания разрешений 422 приложению, в которое перетаскиваются данные. 423 </dd> 424 425 <dt> 426 <code>View.startDragAndDrop()</code> 427 </dt> 428 429 <dd> 430 Новый псевдоним для {@link android.view.View#startDrag View.startDrag()}. Чтобы 431 разрешить перетаскивание между операциями, передайте 432 новый флаг <code>View.DRAG_FLAG_GLOBAL</code>. Если вам нужно предоставить принимающей операции разрешения на чтение или запись URI, 433 передайте новый флаг 434 <code>View.DRAG_FLAG_GLOBAL_URI_READ</code> или 435 <code>View.DRAG_FLAG_GLOBAL_URI_WRITE</code> соответственно. 436 </dd> 437 438 <dt> 439 <code>View.cancelDragAndDrop()</code> 440 </dt> 441 442 <dd> 443 Отменяет текущую операцию перетаскивания. Этот метод может вызвать только 444 приложение, в котором была инициирована операция перетаскивания. 445 </dd> 446 447 <dt> 448 <code>View.updateDragShadow()</code> 449 </dt> 450 451 <dd> 452 Заменяет тень текущей операции перетаскивания. Этот метод может вызвать только приложение, 453 в котором была инициирована операция перетаскивания. 454 </dd> 455 456 <dt> 457 <code>Activity.requestDropPermissions()</code> 458 </dt> 459 460 <dd> 461 Запрашивает разрешения для URI контента, переданных в объекте {@link 462 android.content.ClipData} в {@link android.view.DragEvent}. 463 </dd> 464</dl> 465 466<h2 id="testing">Тестирование приложения в многооконном режиме</h2> 467 468<p> 469 Независимо от того, обновляете ли вы свое приложение для Android N, вам необходимо 470 подтвердить его поведение в многооконном 471 режиме на тот случай, если пользователь попытается запустить его в этом режиме на устройстве с Android N. 472</p> 473 474<h3 id="configuring">Настройка тестового устройства</h3> 475 476<p> 477 Если установить Android N на устройстве, режим разделения 478 экрана будет поддерживаться автоматически. 479</p> 480 481<h3 id="test-non-n">Если приложение было создано без использования N Preview SDK</h3> 482 483<p> 484 Если вы не применяли N Preview SDK для создания приложения и пользователь 485 попытается запустить его в многооконном режиме, система принудительно 486 изменит размер окна приложения, если его ориентация не зафиксирована. 487</p> 488 489<p> 490 Если для приложения не задана фиксированная ориентация, вам 491 следует запустить его на устройстве с Android N и попытаться 492 перевести его в режим разделения экрана. Убедитесь, что приложение 493 работает нормально после принудительного изменения размера. 494</p> 495 496<p> 497 Если для приложения задана фиксированная ориентация, попытайтесь 498 перевести его в многооконный режим. Убедитесь, что при этом 499 приложение остается в полноэкранном режиме. 500</p> 501 502<h3 id="test-mw">Если приложение поддерживает многооконный режим</h3> 503 504<p> 505 Если вы использовали N Preview SDK для создания приложения и не 506 отключили поддержку многооконного режима, проверьте работу 507 приложения, как описано далее, в режимах разделения экрана и произвольной формы. 508</p> 509 510<ul> 511 <li>Запустите приложение в полноэкранном режиме, а затем переключитесь 512 в многооконный режим долгим нажатием кнопки "Обзор". Убедитесь, что приложение корректно переключается между режимами. 513 </li> 514 515 <li>Запустите приложение непосредственно в многооконном режиме 516 и убедитесь, что оно работает нормально. Вы можете запустить приложение в многооконном режиме, нажав 517 кнопку "Обзор", затем длительно нажав строку заголовка приложения и 518 перетащив ее в одну из выделенных областей на экране. 519 </li> 520 521 <li>Измените размер окна приложения в режиме разделения экрана, перетащив линию разделения. 522 Убедитесь, что изменение размера не приводит к сбою и что необходимые 523 элементы интерфейса остаются видимыми. 524 </li> 525 526 <li>Если вы указали минимальные размеры окна приложения, попытайтесь 527 установить размер меньше минимального. Убедитесь в невозможности установить размер 528 меньше указанного минимума. 529 </li> 530 531 <li>Во время всех тестов следите за производительностью приложения — она должна быть приемлемой. Например, 532 убедитесь, что после изменения размера окна приложения не возникает большой 533 задержки обновления интерфейса. 534 </li> 535</ul> 536 537<h4 id="test-checklist">Контрольный список тестирования</h4> 538 539<p> 540 Для проверки производительности приложения в многооконном режиме 541 выполните следующие операции. Попытайтесь выполнить их в режиме разделения экрана и 542 в многооконном режиме, если не указано иное. 543</p> 544 545<ul> 546 <li>Перейдите в многооконный режим и выйдите из него. 547 </li> 548 549 <li>Переключитесь из своего приложения в другое приложение и убедитесь, 550 что приложение работает нормально, если оно видимо, но не активно. Например, если приложение 551 показывает видео, оно должно продолжать воспроизведение, когда 552 пользователь работает с другим приложением. 553 </li> 554 555 <li>В режиме разделения экрана попробуйте перемещать линию 556 разделения, увеличивая и уменьшая окно приложения. Попробуйте выполнить эти операции, когда окна двух 557 приложений находятся рядом и друг над другом. Убедитесь, что приложение не завершается с ошибкой, 558 необходимые элементы видны и изменение размера не занимает 559 слишком много времени. 560 </li> 561 562 <li>Быстро измените размер окна приложения несколько раз подряд. Убедитесь, что 563 приложение не зависает и не вызывает утечку памяти. Информация о проверке использования памяти 564 приложением содержится в документе <a href="{@docRoot}tools/debugging/debugging-memory.html"> 565Анализ использования оперативной памяти</a>. 566 </li> 567 568 <li>Поработайте с приложением в различных оконных конфигурациях и 569 убедитесь, что оно ведет себя должным образом. Текст должен легко читаться, а 570 элементы интерфейса не должны быть слишком маленькими. 571 </li> 572</ul> 573 574<h3 id="test-disabled-mw">Если вы отключили поддержку многооконного режима</h3> 575 576<p> 577 Если вы отключили поддержку многооконного режима, 578 установив атрибут <code>android:resizableActivity="false"</code>, запустите 579 приложение на устройстве с Android N и 580 попытайтесь перевести его в режимы произвольной формы и разделения экрана. Убедитесь, что при этом 581 приложение остается в полноэкранном режиме. 582</p> 583