1 page.title=Multi-Window Support 2 page.metaDescription=New support in Android N for showing more than one app at a time. 3 page.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>In this document</h2> 10 <ol> 11 <li><a href="#overview">Overview</a></li> 12 <li><a href="#lifecycle">Multi-Window Lifecycle</a></li> 13 <li><a href="#configuring">Configuring Your App for Multi-Window 14 Mode</a></li> 15 <li><a href="#running">Running Your App in Multi-Window Mode</a></li> 16 <li><a href="#testing">Testing Your App's Multi-Window Support</a></li> 17 </ol> 18 <h2>See Also</h2> 19 <ol> 20 <li><a href="{@docRoot}training/tv/playback/picture-in-picture.html">Adding 21 Picture-in-Picture</a></li> 22 <li><a class="external-link" 23 href="https://github.com/googlesamples/android-MultiWindowPlayground">Multi-Window 24 Playground sample app</a></li> 25 <li><a class="external-link" 26 href="https://medium.com/google-developers/5-tips-for-preparing-for-multi-window-in-android-n-7bed803dda64" 27 >Five Tips for Preparing for Multi-Window in Android N</a></li> 28 </ol> 29 </div> 30 </div> 31 32 <p> 33 Android 7.0 adds support for displaying more than one app at the 34 same time. On handheld devices, two apps can run side-by-side or 35 one-above-the-other in <em>split-screen</em> mode. On TV devices, apps can 36 use <em>picture-in-picture</em> mode to continue video playback while users 37 are interacting with another app. 38 </p> 39 40 <p> 41 If your app targets Android 7.0 (API level 24) or higher, you can configure how your app 42 handles multi-window display. For example, you can specify your activity's 43 minimum allowable dimensions. You can also disable multi-window display for 44 your app, ensuring that the system only shows your app in full-screen 45 mode. 46 </p> 47 48 <h2 id="overview">Overview</h2> 49 50 <p> 51 Android 7.0 allows several apps to share the screen at once. For 52 example, a user could split the screen, viewing a web page on the left side 53 while composing an email on the right side. The user experience depends on 54 the device: 55 </p> 56 57 <ul> 58 <li>Handheld devices running Android 7.0 offer split-screen 59 mode. In this mode, the system fills the screen with two apps, showing them 60 either side-by-side or one-above-the-other. The user can drag the dividing 61 line separating the two to make one app larger and the other smaller. 62 </li> 63 64 <li>On TV devices, apps can put themselves 65 in <a href="picture-in-picture.html">picture-in-picture mode</a>, allowing 66 them to continue showing content while the user browses or interacts with 67 other apps. 68 </li> 69 70 <li>Manufacturers of larger devices can choose to enable freeform 71 mode, in which the user can freely resize each activity. If the 72 manufacturer enables this feature, the device offers freeform mode in addition 73 to split-screen mode. 74 </li> 75 </ul> 76 77 <img src="{@docRoot}images/android-7.0/mw-splitscreen.png" alt="" width="650" 78 srcset="{@docRoot}images/android-7.0/mw-splitscreen.png 1x, 79 {@docRoot}images/android-7.0/mw-splitscreen_2x.png 2x," 80 id="img-split-screen" /> 81 <p class="img-caption"> 82 <strong>Figure 1.</strong> Two apps running side-by-side in split-screen mode. 83 </p> 84 85 <p> 86 The user can switch into multi-window mode in the following ways: 87 </p> 88 89 <ul> 90 <li>If the user opens the <a href="{@docRoot}guide/components/recents.html">Overview 91 screen</a> and performs a long press on an 92 activity title, they can drag that activity to a highlighted portion of the 93 screen to put the activity in multi-window mode. 94 </li> 95 96 <li>If the user performs a long press on the Overview button, the device puts 97 the current activity in multi-window mode, and opens the Overview screen to 98 let the user choose another activity to share the screen. 99 </li> 100 </ul> 101 102 <p> 103 Users can <a href="{@docRoot}guide/topics/ui/drag-drop.html">drag and 104 drop</a> data from one activity to another while the activities are sharing 105 the screen. 106 107 <h2 id="lifecycle">Multi-Window Lifecycle</h2> 108 109 <p> 110 Multi-window mode does not change the <a href= 111 "{@docRoot}training/basics/activity-lifecycle/index.html">activity 112 lifecycle</a>. 113 </p> 114 115 <p> 116 In multi-window mode, only the activity the user has most recently interacted 117 with is active at a given time. This activity is considered <em>topmost</em>. 118 All other activities are in the paused state, even if they are visible. 119 However, the system gives these paused-but-visible activities higher priority 120 than activities that are not visible. If the user interacts with one of the 121 paused activities, that activity is resumed, and the previously topmost 122 activity is paused. 123 </p> 124 125 <p class="note"> 126 <strong>Note:</strong> In multi-window mode, an app can be in the paused 127 state and still be visible to the user. An app might need to continue its 128 activities even while paused. For example, a video-playing app that is in 129 paused mode but is visible should continue showing its video. For this 130 reason, we recommend that activities that play video <em>not</em> pause the 131 video in their {@link android.app.Activity#onPause onPause()} handlers. 132 Instead, they should pause video in {@link android.app.Activity#onStop 133 onStop()}, and resume playback in {@link android.app.Activity#onStart 134 onStart()}. 135 </p> 136 137 <p> 138 When the user puts an app into multi-window mode, the system notifies the 139 activity of a configuration change, as specified in <a href= 140 "{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime 141 Changes</a>. This also happens when the user resizes the app, or puts the app 142 back into full-screen mode. 143 Essentially, this change has the same activity-lifecycle 144 implications as when the system notifies the app that the device has switched 145 from portrait to landscape mode, except that the device dimensions are 146 changed instead of just being swapped. As discussed in <a href= 147 "{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime 148 Changes</a>, your activity can handle the configuration change itself, or it 149 can allow the system to destroy the activity and recreate it with the new 150 dimensions. 151 </p> 152 153 <p> 154 If the user is resizing a window and makes it larger in either dimension, the 155 system resizes the activity to match the user action and issues <a href= 156 "{@docRoot}guide/topics/resources/runtime-changes.html">runtime changes</a> 157 as needed. If the app lags behind in drawing in newly-exposed areas, the 158 system temporarily fills those areas with the color specified by the {@link 159 android.R.attr#windowBackground windowBackground} attribute or by the default 160 <code>windowBackgroundFallback</code> style attribute. 161 </p> 162 163 <h2 id="configuring">Configuring Your App for Multi-Window Mode</h2> 164 165 <p> 166 If your app targets API level 24 or higher, you can configure how and 167 whether your app's activities support multi-window display. You can set 168 attributes in your manifest to control both size and layout. 169 A root activity's attribute settings apply to all activities 170 within its task stack. For example, if the root activity has 171 <code>android:resizeableActivity</code> set to true, then all activities 172 in the task stack are resizable. 173 </p> 174 175 <p class="note"> 176 <strong>Note:</strong> If you build a multi-orientation app that targets API 177 level 23 or lower, and the user uses the app in 178 multi-window mode, the system forcibly resizes the app. The system presents a 179 dialog box warning the user that the app may behave unexpectedly. The system 180 does <em>not</em> resize fixed-orientation apps; if 181 the user attempts to open a fixed-orientation app under multi-window mode, 182 the app takes over the whole screen. 183 </p> 184 185 <h4 id="resizeableActivity">android:resizeableActivity</h4> 186 187 <p> 188 Set this attribute in your manifest's <a href= 189 "{@docRoot}guide/topics/manifest/activity-element"><code><activity></code></a> 190 or <a href= 191 "{@docRoot}guide/topics/manifest/application-element"><code><application></code></a> 192 element to enable or disable multi-window display: 193 </p> 194 195 <pre> 196 android:resizeableActivity=["true" | "false"] 197 </pre> 198 199 <p> 200 If this attribute is set to true, the activity can be launched in 201 split-screen and freeform modes. If the attribute is set to false, the 202 activity does not support multi-window mode. If this value is false, and the 203 user attempts to launch the activity in multi-window mode, the activity takes 204 over the full screen. 205 </p> 206 207 <p> 208 If your app targets API level 24, but you do not specify a value 209 for this attribute, the attribute's value defaults to true. 210 </p> 211 212 <h4 id="supportsPictureInPicture">android:supportsPictureInPicture</h4> 213 214 <p> 215 Set this attribute in your manifest's <a href= 216 "{@docRoot}guide/topics/manifest/activity-element"><code><activity></code></a> 217 node to indicate whether the activity supports <a href= 218 "{@docRoot}training/tv/playback/picture-in-picture.html">Picture-in-Picture</a> 219 display. This attribute is ignored if <code>android:resizeableActivity</code> 220 is false. 221 </p> 222 223 <pre> 224 android:supportsPictureInPicture=["true" | "false"] 225 </pre> 226 227 <h3 id="layout">Layout attributes</h3> 228 229 <p> 230 With Android 7.0, the <code><layout></code> manifest element 231 supports several attributes that affect how an activity behaves in 232 multi-window mode: 233 </p> 234 235 <dl> 236 <dt> 237 <code>android:defaultWidth</code> 238 </dt> 239 240 <dd> 241 Default width of the activity when launched in freeform mode. 242 </dd> 243 244 <dt> 245 <code>android:defaultHeight</code> 246 </dt> 247 248 <dd> 249 Default height of the activity when launched in freeform mode. 250 </dd> 251 252 <dt> 253 <code>android:gravity</code> 254 </dt> 255 256 <dd> 257 Initial placement of the activity when launched in freeform mode. See the 258 {@link android.view.Gravity} reference for suitable values. 259 </dd> 260 261 <dt> 262 <code>android:minHeight</code>, <code>android:minWidth</code> 263 </dt> 264 265 <dd> 266 Minimum height and minimum width for the activity in both split-screen 267 and freeform modes. If the user moves the divider in split-screen mode 268 to make an activity smaller than the specified minimum, the system crops 269 the activity to the size the user requests. 270 </dd> 271 </dl> 272 273 <p> 274 For example, the following code shows how to specify an activity's default 275 size and location, and its minimum size, when the activity is displayed in 276 freeform mode: 277 </p> 278 279 <pre> 280 <activity android:name=".MyActivity"> 281 <layout android:defaultHeight="500dp" 282 android:defaultWidth="600dp" 283 android:gravity="top|end" 284 android:minHeight="450dp" 285 android:minWidth="300dp" /> 286 </activity> 287 </pre> 288 289 <h2 id="running">Running Your App in Multi-Window Mode</h2> 290 291 <p> 292 Beginning with Android 7.0, the system offers functionality to support apps 293 that can run in multi-window mode. 294 </p> 295 296 <h3 id="disabled-features">Disabled features in multi-window mode</h3> 297 298 <p> 299 Certain features are disabled or ignored when a device is in multi-window 300 mode, because they dont make sense for an activity which may be sharing the 301 device screen with other activities or apps. Such features include: 302 303 <ul> 304 <li>Some <a href="{@docRoot}training/system-ui/index.html">System UI</a> 305 customization options are disabled; for example, apps cannot hide the status 306 bar if they are not running in full-screen mode. 307 </li> 308 309 <li>The system ignores changes to the <code><a href= 310 "{@docRoot}guide/topics/manifest/activity-element.html#screen" 311 >android:screenOrientation</a></code> attribute. 312 </li> 313 </ul> 314 315 <h3 id="change-notification">Multi-window change notification and querying</h3> 316 317 <p> 318 {@link android.app.Activity} offers the following methods to support 319 multi-window display. 320 </p> 321 322 <dl> 323 <dt> 324 {@link android.app.Activity#isInMultiWindowMode isInMultiWindowMode()} 325 </dt> 326 327 <dd> 328 Call to find out if the activity is in multi-window mode. 329 </dd> 330 331 <dt> 332 {@link android.app.Activity#isInPictureInPictureMode 333 isInPictureInPictureMode()} 334 </dt> 335 336 <dd> 337 Call to find out if the activity is in <a href= 338 "{@docRoot}training/tv/playback/picture-in-picture.jd">picture-in-picture</a> 339 mode. 340 <p class="note"> 341 <strong>Note:</strong> Picture-in-picture mode is a special case of 342 multi-window mode. If <code>myActivity.isInPictureInPictureMode()</code> 343 returns true, then <code>myActivity.isInMultiWindowMode()</code> also 344 returns true. 345 </p> 346 </dd> 347 348 <dt> 349 {@link android.app.Activity#onMultiWindowModeChanged 350 onMultiWindowModeChanged()} 351 </dt> 352 353 <dd> 354 The system calls this method whenever the activity goes into or out of 355 multi-window mode. The system passes the method a value of true if the 356 activity is entering multi-window mode, and false if the activity is 357 leaving multi-window mode. 358 </dd> 359 360 <dt> 361 {@link android.app.Activity#onPictureInPictureModeChanged 362 onPictureInPictureModeChanged()} 363 </dt> 364 365 <dd> 366 The system calls this method whenever the activity goes into or out of 367 picture-in-picture mode. The system passes the method a value of true if 368 the activity is entering picture-in-picture mode, and false if the activity 369 is leaving picture-in-picture mode. 370 </dd> 371 </dl> 372 373 <p> 374 The {@link android.app.Fragment} class exposes versions of many of these 375 methods, for example {@link android.app.Fragment#onMultiWindowModeChanged 376 Fragment.onMultiWindowModeChanged()}. 377 </p> 378 379 <h3 id="entering-pip">Entering picture-in-picture mode</h3> 380 381 <p> 382 To put an activity in picture-in-picture mode, call {@link 383 android.app.Activity#enterPictureInPictureMode 384 Activity.enterPictureInPictureMode()}. This method has no effect if the 385 device does not support picture-in-picture mode. For more information, see 386 the <a href= 387 "{@docRoot}training/tv/playback/picture-in-picture.jd">Picture-in-Picture</a> 388 documentation. 389 </p> 390 391 <h3 id="launch">Launch New Activities in Multi-Window Mode</h3> 392 393 <p> 394 When you launch a new activity, you can hint to the system that the new 395 activity should be displayed adjacent to the current one, if possible. To do 396 this, use the intent flag 397 {@link android.content.Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT}. Passing 398 this flag requests the following behavior: 399 </p> 400 401 <ul> 402 <li>If the device is in split-screen mode, the system attempts to create the 403 new activity next to the activity that launched it, so the two activities 404 share the screen. The system is not guaranteed to be able to do this, but it 405 makes the activities adjacent if possible. 406 </li> 407 408 <li>If the device is not in split-screen mode, this flag has no effect. 409 </li> 410 </ul> 411 412 <p> 413 If a device is in freeform mode and you are launching a new activity, you can 414 specify the new activity's dimensions and screen location by calling 415 {@link android.app.ActivityOptions#setLaunchBounds 416 ActivityOptions.setLaunchBounds()}. This method has no effect if 417 the device is not in multi-window mode. 418 </p> 419 420 <p class="note"> 421 <strong>Note:</strong> If you launch an activity within a task stack, the 422 activity replaces the activity on the screen, inheriting all of its 423 multi-window properties. If you want to launch the new activity as a separate 424 window in multi-window mode, you must launch it in a new task stack. 425 </p> 426 427 <h3 id="dnd">Supporting drag and drop</h3> 428 429 <p> 430 Users can <a href="{@docRoot}guide/topics/ui/drag-drop.html">drag and 431 drop</a> data from one activity to another while the two activities are 432 sharing the screen. (Prior to Android 7.0, users could only drag and drop data 433 within a single activity.) For this reason, you may want to add drag and drop 434 functionality to your app if your app does not currently support it. 435 </p> 436 437 438 <dl> 439 <dt> 440 {@link android.view.DragAndDropPermissions} 441 </dt> 442 443 <dd> 444 Token object responsible for specifying the permissions granted to the app 445 that receives a drop. 446 </dd> 447 448 <dt> 449 {@link android.view.View#startDragAndDrop View.startDragAndDrop()} 450 </dt> 451 452 <dd> 453 Alias for {@link android.view.View#startDrag View.startDrag()}. To enable 454 cross-activity drag and drop, pass the flag {@link 455 android.view.View#DRAG_FLAG_GLOBAL}. If you need to give URI permissions to 456 the recipient activity, pass the flags {@link 457 android.view.View#DRAG_FLAG_GLOBAL_URI_READ} or {@link 458 android.view.View#DRAG_FLAG_GLOBAL_URI_WRITE}, as appropriate. 459 </dd> 460 461 <dt> 462 {@link android.view.View#cancelDragAndDrop View.cancelDragAndDrop()} 463 </dt> 464 465 <dd> 466 Cancels a drag operation currently in progress. Can only be called by the 467 app that originated the drag operation. 468 </dd> 469 470 <dt> 471 {@link android.view.View#updateDragShadow View.updateDragShadow()} 472 </dt> 473 474 <dd> 475 Replaces the drag shadow for a drag operation currently in progress. Can 476 only be called by the app that originated the drag operation. 477 </dd> 478 479 <dt> 480 {@link android.app.Activity#requestDragAndDropPermissions 481 Activity.requestDragAndDropPermissions()} 482 </dt> 483 484 <dd> 485 Requests the permissions for the content URIs passed with the {@link 486 android.content.ClipData} contained in a {@link android.view.DragEvent}. 487 </dd> 488 </dl> 489 490 <h2 id="testing">Testing Your App's Multi-Window Support</h2> 491 492 <p> 493 Whether or not your app targets API level 24 or higher, you should 494 verify how it behaves in multi-window mode in case a user tries to launch it 495 in multi-window mode on a device running Android 7.0 or higher. 496 </p> 497 498 <h3 id="configuring">Configuring a Test Device</h3> 499 500 <p> 501 If a device runs Android 7.0 or higher, it automatically supports split-screen 502 mode. 503 </p> 504 505 <h3 id="test-non-n">If your app targets API level 23 or lower</h3> 506 507 <p> 508 If your app targets API level 23 or lower and the user attempts to use 509 the app in multi-window mode, the system forcibly resizes the app unless the 510 app declares a fixed orientation. 511 </p> 512 513 <p> 514 If your app does not declare a fixed orientation, you should launch your app 515 on a device running Android 7.0 or higher and attempt to put the app in 516 split-screen mode. Verify that the user experience is 517 acceptable when the app is forcibly resized. 518 </p> 519 520 <p> 521 If the app declares a fixed orientation, you should attempt to put the app in 522 multi-window mode. Verify that when you do so, the app remains 523 in full-screen mode. 524 </p> 525 526 <h3 id="test-mw">If you support multi-window mode</h3> 527 528 <p> 529 If your app targets API level 24 or higher and does not disable 530 multi-window support, verify the following behavior under both split-screen 531 and freeform modes. 532 </p> 533 534 <ul> 535 <li>Launch the app in full-screen mode, then switch to multi-window mode by 536 long-pressing the Overview button. Verify that the app switches properly. 537 </li> 538 539 <li>Launch the app directly in multi-window mode, and verify that the app 540 launches properly. You can launch an app in multi-window mode by pressing the 541 Overview button, then long-pressing the title bar of your app and dragging it 542 to one of the highlighted areas on the screen. 543 </li> 544 545 <li>Resize your app in split-screen mode by dragging the divider line. 546 Verify that the app resizes without crashing, and that necessary UI elements 547 are visible. 548 </li> 549 550 <li>If you have specified minimum dimensions for your app, attempt to resize 551 the app below those dimensions. Verify that you cannot resize the app to be 552 smaller than the specified minimum. 553 </li> 554 555 <li>Through all tests, verify that your app's performance is acceptable. For 556 example, verify that there is not too long a lag to update the UI after the 557 app is resized. 558 </li> 559 </ul> 560 561 <h4 id="test-checklist">Testing checklist</h4> 562 563 <p> 564 To verify your app's performance in multi-window mode, try the following 565 operations. You should try these operations in both split-screen and 566 multi-window mode, except where otherwise noted. 567 </p> 568 569 <ul> 570 <li>Enter and leave multi-window mode. 571 </li> 572 573 <li>Switch from your app to another app, and verify that the app behaves 574 properly while it is visible but not active. For example, if your app is 575 playing video, verify that the video continues to play while the user is 576 interacting with another app. 577 </li> 578 579 <li>In split-screen mode, try moving the dividing bar to make your app both 580 larger and smaller. Try these operations in both side-by-side and 581 one-above-the-other configurations. Verify that the app does not crash, 582 essential functionality is visible, and the resize operation doesn't take too 583 long. 584 </li> 585 586 <li>Perform several resize operations in rapid succession. Verify that your 587 app doesn't crash or leak memory. For information about checking your app's 588 memory usage, see <a href="{@docRoot}tools/debugging/debugging-memory.html"> 589 Investigating Your RAM Usage</a>. 590 </li> 591 592 <li>Use your app normally in a number of different window configurations, and 593 verify that the app behaves properly. Verify that text is readable, and that 594 UI elements aren't too small to interact with. 595 </li> 596 </ul> 597 598 <h3 id="test-disabled-mw">If you have disabled multi-window support</h3> 599 600 <p> 601 If you disabled multi-window support by setting 602 <code>android:resizeableActivity="false"</code>, you should launch your app on 603 a device running Android 7.0 or higher and attempt to put the app in 604 freeform and split-screen modes. Verify that when you do so, the app remains 605 in full-screen mode. 606 </p> 607