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>&lt;activity&gt;</code> или
174 <code>&lt;application&gt;</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>&lt;activity&gt;</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>&lt;layout&gt;</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&lt;activity android:name=".MyActivity"&gt;
261    &lt;layout android:defaultHeight="500dp"
262          android:defaultWidth="600dp"
263          android:gravity="top|end"
264          android:minimalSize="450dp" /&gt;
265&lt;/activity&gt;
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