Per bug b/27528326 , the minimalSize attribute is removed from N Preview 2, replaced by height and width-specific attributes. Per bug b/27942263 , several method names have changed for DP2. DO NOT SUBMIT until the final pre-DP2 push, this change should not go live before DP2 releases. See first comment for doc stage location. bug: 27927931 bug: 27942263 Change-Id: I011ab244218ab123bd28aa9e8cb3bc8858fff815
598 lines
20 KiB
Plaintext
598 lines
20 KiB
Plaintext
page.title=Multi-Window Support
|
||
page.metaDescription=New support in Android N for showing more than one app at a time.
|
||
page.keywords="multi-window", "android N", "split screen", "free-form"
|
||
|
||
@jd:body
|
||
|
||
<div id="qv-wrapper">
|
||
<div id="qv">
|
||
<h2>In this document</h2>
|
||
<ol>
|
||
<li><a href="#overview">Overview</a></li>
|
||
<li><a href="#lifecycle">Multi-Window Lifecycle</a></li>
|
||
<li><a href="#configuring">Configuring Your App for Multi-Window
|
||
Mode</a></li>
|
||
<li><a href="#running">Running Your App in Multi-Window Mode</a></li>
|
||
<li><a href="#testing">Testing Your App's Multi-Window Support</a></li>
|
||
</ol>
|
||
<h2>See Also</h2>
|
||
<ol>
|
||
<li><a class="external-link"
|
||
href="https://github.com/googlesamples/android-MultiWindowPlayground">Multi-Window
|
||
Playground sample app</a></li>
|
||
<li><a class="external-link"
|
||
href="https://medium.com/google-developers/5-tips-for-preparing-for-multi-window-in-android-n-7bed803dda64"
|
||
>Five Tips for Preparing for Multi-Window in Android N</a></li>
|
||
</ol>
|
||
</div>
|
||
</div>
|
||
|
||
<p>
|
||
Android N adds support for displaying more than one app at the
|
||
same time. On handheld devices, two apps can run side-by-side or
|
||
one-above-the-other in <em>split-screen</em> mode. On TV devices, apps can
|
||
use <em>picture-in-picture</em> mode to continue video playback while users
|
||
are interacting with another app.
|
||
</p>
|
||
|
||
<p>
|
||
If you build your app with the N Preview SDK, you can configure how your app
|
||
handles multi-window display. For example, you can specify your activity's
|
||
minimum allowable dimensions. You can also disable multi-window display for
|
||
your app, ensuring that the system only shows your app in full-screen
|
||
mode.
|
||
</p>
|
||
|
||
<h2 id="overview">Overview</h2>
|
||
|
||
<p>
|
||
Android N allows several apps to share the screen at once. For
|
||
example, a user could split the screen, viewing a web page on the left side
|
||
while composing an email on the right side. The user experience depends on
|
||
the device:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Handheld devices running Android N offer split-screen
|
||
mode. In this mode, the system fills the screen with two apps, showing them
|
||
either side-by-side or one-above-the-other. The user can drag the dividing
|
||
line separating the two to make one app larger and the other smaller.
|
||
</li>
|
||
|
||
<li>On Nexus Player running Android N, apps can put themselves
|
||
in <a href="picture-in-picture.html">picture-in-picture mode</a>, allowing
|
||
them to continue showing content while the user browses or interacts with
|
||
other apps.
|
||
</li>
|
||
|
||
<li>Manufacturers of larger devices can choose to enable freeform
|
||
mode, in which the user can freely resize each activity. If the
|
||
manufacturer enables this feature, the device offers freeform mode in addition
|
||
to split-screen mode.
|
||
</li>
|
||
</ul>
|
||
|
||
<img src="{@docRoot}preview/images/mw-splitscreen.png" alt="" width="650"
|
||
srcset="{@docRoot}preview/images/mw-splitscreen.png 1x,
|
||
{@docRoot}preview/images/mw-splitscreen_2x.png 2x,"
|
||
id="img-split-screen" />
|
||
<p class="img-caption">
|
||
<strong>Figure 1.</strong> Two apps running side-by-side in split-screen mode.
|
||
</p>
|
||
|
||
<p>
|
||
The user can switch into multi-window mode in the following ways:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>If the user opens the <a href="{@docRoot}guide/components/recents.html">Overview
|
||
screen</a> and performs a long press on an
|
||
activity title, they can drag that activity to a highlighted portion of the
|
||
screen to put the activity in multi-window mode.
|
||
</li>
|
||
|
||
<li>If the user performs a long press on the Overview button, the device puts
|
||
the current activity in multi-window mode, and opens the Overview screen to
|
||
let the user choose another activity to share the screen.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>
|
||
Users can <a href="{@docRoot}guide/topics/ui/drag-drop.html">drag and
|
||
drop</a> data from one activity to another while the activities are sharing
|
||
the screen. (Previously, users could only drag and drop data within a single
|
||
activity.)
|
||
</p>
|
||
|
||
<h2 id="lifecycle">Multi-Window Lifecycle</h2>
|
||
|
||
<p>
|
||
Multi-window mode does not change the <a href=
|
||
"{@docRoot}training/basics/activity-lifecycle/index.html">activity
|
||
lifecycle</a>.
|
||
</p>
|
||
|
||
<p>
|
||
In multi-window mode, only the activity the user has most recently interacted
|
||
with is active at a given time. This activity is considered <em>topmost</em>.
|
||
All other activities are in the paused state, even if they are visible.
|
||
However, the system gives these paused-but-visible activities higher priority
|
||
than activities that are not visible. If the user interacts with one of the
|
||
paused activities, that activity is resumed, and the previously topmost
|
||
activity is paused.
|
||
</p>
|
||
|
||
<p class="note">
|
||
<strong>Note:</strong> In multi-window mode, an app can be in the paused
|
||
state and still be visible to the user. An app might need to continue its
|
||
activities even while paused. For example, a video-playing app that is in
|
||
paused mode but is visible should continue showing its video. For this
|
||
reason, we recommend that activities that play video <em>not</em> pause the
|
||
video in their {@link android.app.Activity#onPause onPause()} handlers.
|
||
Instead, they should pause video in {@link android.app.Activity#onStop
|
||
onStop()}, and resume playback in {@link android.app.Activity#onStart
|
||
onStart()}.
|
||
</p>
|
||
|
||
<p>
|
||
When the user puts an app into multi-window mode, the system notifies the
|
||
activity of a configuration change, as specified in <a href=
|
||
"{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime
|
||
Changes</a>. Essentially, this change has the same activity-lifecycle
|
||
implications as when the system notifies the app that the device has switched
|
||
from portrait to landscape mode, except that the device dimensions are
|
||
changed instead of just being swapped. As discussed in <a href=
|
||
"{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime
|
||
Changes</a>, your activity can handle the configuration change itself, or it
|
||
can allow the system to destroy the activity and recreate it with the new
|
||
dimensions.
|
||
</p>
|
||
|
||
<p>
|
||
If the user is resizing a window and makes it larger in either dimension, the
|
||
system resizes the activity to match the user action and issues <a href=
|
||
"{@docRoot}guide/topics/resources/runtime-changes.html">runtime changes</a>
|
||
as needed. If the app lags behind in drawing in newly-exposed areas, the
|
||
system temporarily fills those areas with the color specified by the {@link
|
||
android.R.attr#windowBackground windowBackground} attribute or by the default
|
||
<code>windowBackgroundFallback</code> style attribute.
|
||
</p>
|
||
|
||
<h2 id="configuring">Configuring Your App for Multi-Window Mode</h2>
|
||
|
||
<p>
|
||
If your app targets Android N, you can configure how and
|
||
whether your app's activities support multi-window display. You can set
|
||
attributes in your manifest to control both size and layout.
|
||
A root activity's attribute settings apply to all activities
|
||
within its task stack. For example, if the root activity has
|
||
<code>android:resizeableActivity</code> set to true, then all activities
|
||
in the task stack are resizeable.
|
||
</p>
|
||
|
||
<p class="note">
|
||
<strong>Note:</strong> If you build a multi-orientation app with a version of the
|
||
SDK lower than Android N, and the user uses the app in
|
||
multi-window mode, the system forcibly resizes the app. The system presents a
|
||
dialog box warning the user that the app may behave unexpectedly. The system
|
||
does <em>not</em> resize fixed-orientation apps; if
|
||
the user attempts to open a fixed-orientation app under multi-window mode,
|
||
the app takes over the whole screen.
|
||
</p>
|
||
|
||
<h4 id="resizeableActivity">android:resizeableActivity</h4>
|
||
<p>
|
||
Set this attribute in your manifest's <code><activity></code> or
|
||
<code><application></code> node to enable or disable multi-window
|
||
display:
|
||
</p>
|
||
|
||
<pre>
|
||
android:resizeableActivity=["true" | "false"]
|
||
</pre>
|
||
|
||
<p>
|
||
If this attribute is set to true, the activity can be launched in
|
||
split-screen and freeform modes. If the attribute is set to false, the
|
||
activity does not support multi-window mode. If this value is false, and the
|
||
user attempts to launch the activity in multi-window mode, the activity takes
|
||
over the full screen.
|
||
</p>
|
||
|
||
<p>
|
||
If your app targets Android N, but you do not specify a value
|
||
for this attribute, the attribute's value defaults to true.
|
||
</p>
|
||
|
||
<h4 id="supportsPictureInPicture">android:supportsPictureInPicture</h4>
|
||
|
||
<p>
|
||
Set this attribute in your manifest's <code><activity></code> node to
|
||
indicate whether the activity supports picture-in-picture display. This
|
||
attribute is ignored if <code>android:resizeableActivity</code> is false.
|
||
</p>
|
||
|
||
<pre>
|
||
android:supportsPictureInPicture=["true" | "false"]
|
||
</pre>
|
||
|
||
<h3 id="layout">Layout attributes</h3>
|
||
|
||
<p>
|
||
With Android N, the <code><layout></code> manifest element
|
||
supports several attributes that affect how an activity behaves in
|
||
multi-window mode:
|
||
</p>
|
||
|
||
<dl>
|
||
<dt>
|
||
<code>android:defaultWidth</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Default width of the activity when launched in freeform mode.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>android:defaultHeight</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Default height of the activity when launched in freeform mode.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>android:gravity</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Initial placement of the activity when launched in freeform mode. See the
|
||
{@link android.view.Gravity} reference for suitable values.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>android:minimalHeight</code>, <code>android:minimalWidth</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Minimum height and minimum width for the activity in both split-screen
|
||
and freeform modes. If the user moves the divider in split-screen mode
|
||
to make an activity smaller than the specified minimum, the system crops
|
||
the activity to the size the user requests.
|
||
</dd>
|
||
</dl>
|
||
|
||
<p>
|
||
For example, the following code shows how to specify an activity's default
|
||
size and location, and its minimum size, when the activity is displayed in
|
||
freeform mode:
|
||
</p>
|
||
|
||
<pre>
|
||
<activity android:name=".MyActivity">
|
||
<layout android:defaultHeight="500dp"
|
||
android:defaultWidth="600dp"
|
||
android:gravity="top|end"
|
||
android:minimalHeight="450dp"
|
||
android:minimalWidth="300dp" />
|
||
</activity>
|
||
</pre>
|
||
|
||
<h2 id="running">Running Your App in Multi-Window Mode</h2>
|
||
|
||
<p>
|
||
Android N offers new functionality to support apps that can run
|
||
in multi-window mode.
|
||
</p>
|
||
|
||
<h3 id="disabled-features">Disabled features in multi-window mode</h3>
|
||
|
||
<p>
|
||
Certain features are disabled or ignored when a device is in multi-window
|
||
mode, because they don’t make sense for an activity which may be sharing the
|
||
device screen with other activities or apps. Such features include:
|
||
|
||
<ul>
|
||
<li>Some <a href="{@docRoot}training/system-ui/index.html">System UI</a>
|
||
customization options are disabled; for example, apps cannot hide the status
|
||
bar if they are not running in full-screen mode.
|
||
</li>
|
||
|
||
<li>The system ignores changes to the <code><a href=
|
||
"{@docRoot}guide/topics/manifest/activity-element.html#screen"
|
||
>android:screenOrientation</a></code> attribute.
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 id="change-notification">Multi-window change notification and querying</h3>
|
||
|
||
<p>
|
||
The following new methods have been added to the {@link android.app.Activity}
|
||
class to support multi-window display. For details on each method, see the
|
||
<a href="{@docRoot}preview/setup-sdk.html#docs-dl">N Preview SDK
|
||
Reference</a>.
|
||
</p>
|
||
|
||
<dl>
|
||
<dt>
|
||
<code>Activity.isInMultiWindowMode()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Call to find out if the activity is in multi-window mode.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>Activity.isInPictureInPictureMode()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Call to find out if the activity is in picture-in-picture mode.
|
||
|
||
<p class="note">
|
||
<strong>Note:</strong> Picture-in-picture mode is a special case of
|
||
multi-window mode. If <code>myActivity.isInPictureInPictureMode()</code>
|
||
returns true, then <code>myActivity.isInMultiWindowMode()</code> also
|
||
returns true.
|
||
</p>
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>Activity.onMultiWindowModeChanged()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
The system calls this method whenever the activity goes into or out of
|
||
multi-window mode. The system passes the method a value of true if the
|
||
activity is entering multi-window mode, and false if the activity is
|
||
leaving multi-window mode.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>Activity.onPictureInPictureModeChanged()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
The system calls this method whenever the activity goes into or out of
|
||
picture-in-picture mode. The system passes the method a value of true if
|
||
the activity is entering picture-in-picture mode, and false if the activity
|
||
is leaving picture-in-picture mode.
|
||
</dd>
|
||
</dl>
|
||
|
||
<p>
|
||
There are also {@link android.app.Fragment} versions of each of these
|
||
methods, for example <code>Fragment.isInMultiWindowMode()</code>.
|
||
</p>
|
||
|
||
<h3 id="entering-pip">Entering picture-in-picture mode</h3>
|
||
|
||
<p>
|
||
To put an activity in picture-in-picture mode, call the new method
|
||
<code>Activity.enterPictureInPictureMode()</code>. This method has no effect if
|
||
the device does not support picture-in-picture mode. For more information,
|
||
see the <a href="picture-in-picture.html">Picture-in-Picture</a> documentation.
|
||
</p>
|
||
|
||
<h3 id="launch">Launch New Activities in Multi-Window Mode</h3>
|
||
|
||
<p>
|
||
When you launch a new activity, you can hint to the system that the new
|
||
activity should be displayed adjacent to the current one, if possible. To do
|
||
this, use the flag
|
||
<code>Intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT</code>. Passing
|
||
this flag requests the following behavior:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>If the device is in split-screen mode, the system attempts to create the
|
||
new activity next to the activity that launched it, so the two activities
|
||
share the screen. The system is not guaranteed to be able to do this, but it
|
||
makes the activities adjacent if possible.
|
||
</li>
|
||
|
||
<li>If the device is not in split-screen mode, this flag has no effect.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>
|
||
If a device is in freeform mode and you are launching a new activity, you can
|
||
specify the new activity's dimensions and screen location by calling
|
||
<code>ActivityOptions.setLaunchBounds()</code>. This method has no effect if
|
||
the device is not in multi-window mode.
|
||
</p>
|
||
|
||
<p class="note">
|
||
<strong>Note:</strong> If you launch an activity within a task stack, the
|
||
activity replaces the activity on the screen, inheriting all of its
|
||
multi-window properties. If you want to launch the new activity as a separate
|
||
window in multi-window mode, you must launch it in a new task stack.
|
||
</p>
|
||
|
||
<h3 id="dnd">Supporting drag and drop</h3>
|
||
|
||
<p>
|
||
Users can <a href="{@docRoot}guide/topics/ui/drag-drop.html">drag and
|
||
drop</a> data from one activity to another while the two activities are
|
||
sharing the screen. (Previously, users could only drag and drop data within a
|
||
single activity.) For this reason, you may want to add drag and drop
|
||
functionality to your app if your app does not currently support it.
|
||
</p>
|
||
|
||
<p>
|
||
The N Preview SDK extends the <a href=
|
||
"{@docRoot}reference/android/view/package-summary.html"><code>android.view</code></a>
|
||
package to support cross-app drag and drop. For details on the following
|
||
classes and methods, see the <a href="{@docRoot}preview/setup-sdk.html#docs-dl">N
|
||
Preview SDK Reference</a>.
|
||
</p>
|
||
|
||
<dl>
|
||
<dt>
|
||
<code>android.view.DropPermissions</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Token object responsible for specifying the permissions granted to the app
|
||
that receives a drop.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>View.startDragAndDrop()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
New alias for {@link android.view.View#startDrag View.startDrag()}. To
|
||
enable cross-activity drag and drop, pass the new flag
|
||
<code>View.DRAG_FLAG_GLOBAL</code>. If you need to give URI permissions to
|
||
the recipient activity, pass the new flags
|
||
<code>View.DRAG_FLAG_GLOBAL_URI_READ</code> or
|
||
<code>View.DRAG_FLAG_GLOBAL_URI_WRITE</code>, as appropriate.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>View.cancelDragAndDrop()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Cancels a drag operation currently in progress. Can only be called by the
|
||
app that originated the drag operation.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>View.updateDragShadow()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Replaces the drag shadow for a drag operation currently in progress. Can
|
||
only be called by the app that originated the drag operation.
|
||
</dd>
|
||
|
||
<dt>
|
||
<code>Activity.requestDropPermissions()</code>
|
||
</dt>
|
||
|
||
<dd>
|
||
Requests the permissions for the content URIs passed with the {@link
|
||
android.content.ClipData} contained in a {@link android.view.DragEvent}.
|
||
</dd>
|
||
</dl>
|
||
|
||
<h2 id="testing">Testing Your App's Multi-Window Support</h2>
|
||
|
||
<p>
|
||
Whether or not you update your app for Android N, you should
|
||
verify how it behaves in multi-window mode in case a user tries to launch it
|
||
in multiwindow mode on a device running Android N.
|
||
</p>
|
||
|
||
<h3 id="configuring">Configuring a Test Device</h3>
|
||
|
||
<p>
|
||
If you install Android N on a device, split-screen mode is
|
||
automatically supported.
|
||
</p>
|
||
|
||
<h3 id="test-non-n">If your app was not built with the N Preview SDK</h3>
|
||
|
||
<p>
|
||
If you did not build your app with the N Preview SDK and the user attempts to use
|
||
the app in multi-window mode, the system forcibly resizes the app unless the app
|
||
declares a fixed orientation.
|
||
</p>
|
||
|
||
<p>
|
||
If your app does not declare a fixed orientation, you should launch your app
|
||
on a device running Android N and attempt to put the app in
|
||
split-screen mode. Verify that the user experience is
|
||
acceptable when the app is forcibly resized.
|
||
</p>
|
||
|
||
<p>
|
||
If the app declares a fixed orientation, you should attempt to put the app in
|
||
multi-window mode. Verify that when you do so, the app remains
|
||
in full-screen mode.
|
||
</p>
|
||
|
||
<h3 id="test-mw">If you support multi-window mode</h3>
|
||
|
||
<p>
|
||
If you built your app with the N Preview SDK and have not disabled
|
||
multi-window support, verify the following behavior under both split-screen
|
||
and freeform modes.
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Launch the app in full-screen mode, then switch to multi-window mode by
|
||
long-pressing the Overview button. Verify that the app switches properly.
|
||
</li>
|
||
|
||
<li>Launch the app directly in multi-window mode, and verify that the app
|
||
launches properly. You can launch an app in multi-window mode by pressing the
|
||
Overview button, then long-pressing the title bar of your app and dragging it
|
||
to one of the highlighted areas on the screen.
|
||
</li>
|
||
|
||
<li>Resize your app in split-screen mode by dragging the divider line.
|
||
Verify that the app resizes without crashing, and that necessary UI elements
|
||
are visible.
|
||
</li>
|
||
|
||
<li>If you have specified minimum dimensions for your app, attempt to resize
|
||
the app below those dimensions. Verify that you cannot resize the app to be
|
||
smaller than the specified minimum.
|
||
</li>
|
||
|
||
<li>Through all tests, verify that your app's performance is acceptable. For
|
||
example, verify that there is not too long a lag to update the UI after the
|
||
app is resized.
|
||
</li>
|
||
</ul>
|
||
|
||
<h4 id="test-checklist">Testing checklist</h4>
|
||
|
||
<p>
|
||
To verify your app's performance in multi-window mode, try the following
|
||
operations. You should try these operations in both split-screen and
|
||
multi-window mode, except where otherwise noted.
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Enter and leave multi-window mode.
|
||
</li>
|
||
|
||
<li>Switch from your app to another app, and verify that the app behaves
|
||
properly while it is visible but not active. For example, if your app is
|
||
playing video, verify that the video continues to play while the user is
|
||
interacting with another app.
|
||
</li>
|
||
|
||
<li>In split-screen mode, try moving the dividing bar to make your app both
|
||
larger and smaller. Try these operations in both side-by-side and
|
||
one-above-the-other configurations. Verify that the app does not crash,
|
||
essential functionality is visible, and the resize operation doesn't take too
|
||
long.
|
||
</li>
|
||
|
||
<li>Perform several resize operations in rapid succession. Verify that your
|
||
app doesn't crash or leak memory. For information about checking your app's
|
||
memory usage, see <a href="{@docRoot}tools/debugging/debugging-memory.html">
|
||
Investigating Your RAM Usage</a>.
|
||
</li>
|
||
|
||
<li>Use your app normally in a number of different window configurations, and
|
||
verify that the app behaves properly. Verify that text is readable, and that
|
||
UI elements aren't too small to interact with.
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 id="test-disabled-mw">If you have disabled multi-window support</h3>
|
||
|
||
<p>
|
||
If you disabled multi-window support by setting
|
||
<code>android:resizableActivity="false"</code>, you should launch your app on
|
||
a device running Android N and attempt to put the app in
|
||
freeform and split-screen modes. Verify that when you do so, the app remains
|
||
in full-screen mode.
|
||
</p>
|