Zygote
Input & windowsintermediate

Multi-window and large screens

Split screen, freeform, picture-in-picture, foldables and desktop windowing: what happens to an Activity when it no longer owns the display — and why 'resizable' became the default assumption.

12 minAPI 24–37 · 17interactivequizverified 2026-10-27

For most of Android's life an Activity could assume it owned the screen. It could lock the orientation, assume the window was full-size, and treat a configuration change as a rare event. Multi-window broke the first two assumptions; large screens and desktop windowing are now breaking the third.

TL;DR#

  • Split screen arrived in API 24Android 7.0: two Activities share the display.
  • Picture-in-picture arrived in API 26Android 8.0; freeform windows exist for desktop-style environments.
  • An Activity in multi-window can be resized, paused but visible, and focused or not — four states that used to be conflated.
  • Window size classes are the recommended way to reason about layout instead of screen size in dp.
  • The platform's direction is adaptive-first: on large screens, manifest restrictions on orientation and resizability are being phased out, and desktop windowing brings freeform windows to tablets.

Mental model#

Think of a desk that can hold several documents.

On a phone, the desk has room for one sheet at a time, and the sheet is always the same size. On a tablet, the desk holds two sheets side by side, and each sheet gets half the width. In desktop windowing, sheets can be any size and can overlap.

The sheet is an Activity. What changed is not the sheet's content but the assumption that the desk always gives it the whole surface.

Where the analogy breaks#

Documents do not reflow when the desk changes. An Activity must re-layout, and its Configuration changes — which historically meant the Activity was destroyed and recreated. That recreation is the part developers notice, and the reason android:configChanges and ViewModel exist. On a desk, nothing is thrown away when you move a sheet.

The big picture#

Loading diagram…
Text description of this diagram

The window stack from wallpaper through the application band to the system bars. Two app windows share the application band, so neither can draw over the other: in split screen they are siblings in the same band rather than one being on top of the other. The divider between them is a system window with its own drag region, and the IME sits in its own band above both.

The important part is that both apps are in the same band. Neither is "the top app" in the old sense; they are siblings, and the system decides which one has focus.

Deep dive#

The four states#

Before multi-window, an Activity was essentially resumed-and-visible or stopped. Multi-window splits that into a matrix:

StateVisibleFocusedReceives input
Full-screen, resumedyesyesyes
Split, focusedyesyesyes
Split, visible but not focusedyesnono (except its own window chrome)
Picture-in-pictureyesnolimited
Stoppednonono

The middle row is the new one: an Activity can be visible but not resumed, which is why onPause no longer means "the user cannot see you". A video app in split screen must keep playing — that is what Activity.onTopResumedActivityChanged and the multi-window lifecycle callbacks are for.

Configuration changes#

Whenever the window size, orientation, density or available screen changes, the Activity's Configuration changes. By default the system destroys and recreates the Activity to apply it. That is expensive and, for a resize, often unnecessary.

Three tools reduce the cost:

  • android:configChanges in the manifest lets the Activity handle the change itself. Useful for size and orientation if the layout can adapt without recreation.
  • ViewModel survives recreation, so state does not have to be re-fetched.
  • SavedStateHandle persists small state across process death as well as recreation.

Window size classes#

Reasoning about "phone vs tablet" is fragile: a foldable can be both within one session, and a resizable desktop window can be any size. The recommended model is window size classes — compact, medium, expanded — computed from the window's dimensions, not the device's.

In Compose, adaptive layouts use the window size class to choose between a bottom bar, a navigation rail and a permanent drawer. In Views, the same decision is a resource qualifier (layout-w600dp) or a runtime check on the window metrics.

Activity embedding#

On a large screen, a list-detail layout is often two Activities side by side. Activity embedding lets you host a second Activity inside a container in the first Activity's layout, so the two can be developed and navigated independently.

The benefit is architectural: the detail screen keeps its own lifecycle, task and deep link, while the layout is a single pane on a phone and two panes on a tablet. The cost is that the host Activity must manage the embedded Activity's lifecycle and state.

Picture-in-picture#

PiP puts an Activity into a small always-on-top window. It is a window with its own type and a restricted interaction model: the user can move and dismiss it, but not resize it freely.

The lifecycle consequence is that a PiP Activity is visible but not focused, and may be paused. Video apps handle this by continuing playback and hiding controls that need focus.

Freeform and desktop windowing#

Freeform windows — arbitrarily sized, movable, overlapping — have existed for some Android form factors for years. Desktop windowing brings the model to tablets: apps appear in resizable windows with title bars, and the user can arrange several at once.

For an app, the implications are the same as multi-window, only more so: the window can be any size, the orientation can change without the device rotating, and "full screen" is a user choice rather than a default.

The large-screen behaviour changes#

The change is not optional: the manifest attributes that used to force orientation stop being honoured. The practical response is to make every screen resizable and to stop treating a configuration change as an error path.

Testing the window, not the device#

The reliable way to test adaptive behaviour is to resize the window, not to buy more devices. On a debuggable build, adb shell wm size and the resizable emulator configurations let you exercise compact, medium and expanded widths on one image.

Why configuration changes used to destroy the Activity#

The original design treated a configuration change as a restart: the Activity was destroyed, the new configuration was applied, and a new instance was created. That was simple and correct, and it was expensive for exactly the case that became common — a rotation, or a window resize.

The modern toolset does not remove the recreation; it makes it cheap and safe:

  • ViewModel keeps state across recreation.
  • SavedStateHandle keeps state across process death.
  • configChanges avoids recreation when the Activity can adapt in place.
  • Compose recomposes rather than recreating, so a Compose screen handles a size change without an Activity restart.

Even so, a resize is a real event that must invalidate caches — a bitmap decoded for the old size, a layout computed for the old width. Handling it well is less about avoiding the callback and more about making the recomputation cheap.

The window size class thresholds#

The size classes are defined by breakpoints in width and height, in dp.2

ClassWidth
Compactunder 600 dp
Medium600–839 dp
Expanded840 dp and up

A phone in portrait is compact; in landscape it may be medium; a tablet is expanded; a freeform window can be any of the three. The thresholds are not arbitrary — they correspond roughly to where a two-pane layout becomes readable.

The point of using classes rather than raw dp is that the decision ("show a rail") is stable across devices, while the exact width is not.

Multi-window and the back stack#

Each window is associated with a task, and each task has a back stack. In split screen, the two windows are two tasks, and the back gesture applies to the focused one.

Desktop windowing complicates this: a freeform window can contain a task that the user minimises, and the recents view becomes a window switcher rather than a task switcher. The back stack survives, but the affordance changes.

What breaks first#

When an app that assumed full-screen meets a resizable window, the failures are predictable:

  1. Fixed-size dialogs that overflow a narrow window.
  2. Hardcoded paddings that assume a status bar height in pixels.
  3. Camera or video surfaces that lock an aspect ratio and leave letterboxing.
  4. Orientation-locked screens that cannot rotate with the window.
  5. Saved state that assumes the screen size did not change.

Each is a small fix, and each is invisible until the app runs in a window it did not expect.

How it evolved#

API 1–API 23Single windowone Activity owns the displayAPI 1
API 24 →Split screentwo Activities share the displayAPI 24
API 26 →Picture-in-picturea small always-on-top windowAPI 26
API 32 →Adaptivesize classes, embedding, desktop windowingAPI 32
Interface changes16 releases
APIVersionWhat changed
11.0
  • Pull-down notification shade
  • Home screen with widgets
31.5 Cupcake
  • Home screen widgets and folders
92.3 Gingerbread
  • New UI with dark theme and green accents
113.0 Honeycomb
  • The Holo design language arrives
123.1 Honeycomb
  • Resizable widgets
164.1 Jelly Bean
  • Project Butter: vsync-driven, smooth UI
  • Expandable notifications
204.4W KitKat (Wear)
  • Voice-driven card UI
215.0 Lollipop
  • Material Design
  • Notifications on the lock screen
247.0 Nougat
  • Quick Settings tiles
  • Direct Reply in notifications
268.0 Oreo
  • Notification channels
289 Pie
  • Dark theme groundwork
2910
  • System-wide dark theme
3011
  • Conversation notifications and bubbles
  • Media controls in Quick Settings
3112
  • Material You dynamic colour
3313 Tiramisu
  • Themed app icons
  • Runtime notification permission
3616 Baklava
  • Material 3 Expressive
  • Live Updates notifications

Under the hood#

Curiosity corner#

  • A foldable is two devices in one session. The same Activity can see a compact window and an expanded one without the process ever restarting, if it declares the right configChanges.
  • The divider is a window. It has its own input handling and its own system type, which is why dragging it feels different from dragging inside an app.
  • Desktop windowing makes the phone's recents model look simple. A task in a freeform window can be minimised, maximised and restored independently of the back stack.

Try it#

Resize the display
adb shell wm size 720x1600
Example output
Physical size: 1080x2400
Override size: 720x1600
Check the current configuration
adb shell dumpsys activity configuration | head -5
Example output
mGlobalConfiguration={1.0 310mcc... 720x1600 sw360dp w360dp h772dp}
Enter split screen
adb shell am start --windowingMode 3 com.example.app/.MainActivity
Example output
Success

Check yourself#

Check yourself

1 / 12

Why does the system deliver input to an app through a socket pair rather than a Binder call?

0 answered · 0 correct

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsBehavior changes: Apps targeting Android 16 or higherdeveloper.android.comaccessed 2026-10-27↩
  2. docsBuild adaptive layouts with Composedeveloper.android.comaccessed 2026-10-27↩
  3. docsLarge screens overviewdeveloper.android.comaccessed 2026-10-27↩
  4. docsBehavior changes: Apps targeting Android 12developer.android.comaccessed 2026-10-27↩
  5. docsLayers and displayssource.android.comaccessed 2026-10-27↩