Home | History | Annotate | Download | only in ui
      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>&lt;activity&gt;</code></a>
    190   or <a href=
    191   "{@docRoot}guide/topics/manifest/application-element"><code>&lt;application&gt;</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>&lt;activity&gt;</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>&lt;layout&gt;</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 &lt;activity android:name=".MyActivity"&gt;
    281     &lt;layout android:defaultHeight="500dp"
    282           android:defaultWidth="600dp"
    283           android:gravity="top|end"
    284           android:minHeight="450dp"
    285           android:minWidth="300dp" /&gt;
    286 &lt;/activity&gt;
    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