All articles

Technical

Optimising Android TWA Apps for Split-Screen and Multi-Window

September 8, 2026 · 8 min read

Android devices are no longer restricted to uniform, single-screen form factors. With the expansion of tablets, dual-screen foldables, and Chromebooks, users routinely display multiple applications simultaneously. Android supports this through multi-window configurations, which include split-screen mode, picture-in-picture mode, and freeform windowing. For developers distributing a Progressive Web App (PWA) via a Trusted Web Activity (TWA), ensuring that the application adapts fluidly to these dynamic window transitions is critical for passing Google Play reviews and providing a premium user experience.

Understanding Android Multi-Window Modes

When your PWA runs inside a TWA, it is hosted by a specialized instance of the user's default browser (such as Chrome) within an Android Activity wrapper. Because it operates within a native activity, the TWA is subject to the same window lifecycle transitions as any native application. There are three primary windowing modes on modern Android systems:

  • Split-Screen Mode: Two apps share the screen, partitioned either vertically or horizontally. The user can adjust the partition ratio, forcing both applications to resize in real-time.
  • Freeform Mode: Common on desktop-like environments such as ChromeOS or Samsung DeX, where apps run in floating, resizable windows.
  • Picture-in-Picture (PiP) Mode: Primarily used for video playback, allowing a small overlay window to persist while the user interacts with another app.

By default, apps targeting modern Android API levels are resizable. However, if your web application relies on static layout dimensions or fails to manage state changes during a resize event, users may experience UI clipping, visual jumps, or catastrophic data loss caused by unexpected page reloads.

Configuring the Android Manifest for Resizetability

To control how your TWA behaves when entering multi-window mode, you must verify the configuration of the native Android wrapper. In your build setup, this is determined by the properties of the launch activity. The primary attribute governing this behavior is android:resizeableActivity.

If you build your TWA manually or configure the manifest directly, ensure this attribute is set to true within the <activity> element of your AndroidManifest.xml:

<activity android:name="com.google.android.customtabs.trusted.LauncherActivity" android:resizeableActivity="true">

Setting this to true ensures that your app can enter split-screen and freeform modes. If set to false, Android will force the app into compatibility mode on large screens, often letterboxing the UI with black bars and showing a warning to the user that the app may not work as intended.

Web-Side Responsive Layouts for Extreme Aspect Ratios

Inside the TWA wrapper, your web code must handle sudden and drastic layout modifications. A split-screen partition can reduce your app's horizontal resolution to a fraction of the screen width, or compress the height significantly when the soft keyboard is active. Traditional responsive design principles apply, but they must be tuned for these extreme aspect ratios.

To guarantee layout integrity, avoid using hardcoded absolute dimensions for layout containers. Implement fluid grids using modern CSS techniques such as Flexbox and CSS Grid. Use relative CSS viewport units with caution:

CSS UnitBehavior in Split-ScreenRecommended Alternative
vwEvaluates to the width of the active TWA window container, not the physical screen.Use percentage-based widths inside a max-width wrapper.
vhEvaluates to the height of the active container. Dynamic interface elements like the address bar or soft keyboard will cause recalculations.Use container queries or layout units like dvh (dynamic viewport height).

CSS Container Queries provide an excellent mechanism for split-screen layouts. Instead of querying the screen size using media queries, container queries style elements based on the exact width of their parent container. This is highly effective when a component needs to render differently in a narrow split-screen window compared to a full-screen layout on a tablet.

Managing Resize Observers and Layout recalculations

When the window size changes in real-time as a user drags the split-screen divider, your JavaScript engine may need to recalculate complex layout dimensions, re-render charts, or adjust infinite scroll triggers. Standard window resize listeners can fire dozens of times per second during a drag operation, causing frame drops and visual stutter.

To handle this efficiently, use the ResizeObserver API on specific wrapper components rather than attaching global event listeners to the window object. Combine this with a debounce or throttle mechanism to limit the execution rate of heavy rendering calculations:

let timeoutId;
const observer = new ResizeObserver(entries => {
  clearTimeout(timeoutId);
  timeoutId = setTimeout(() => {
    // Perform layout recalculation here
  }, 100);
});
observer.observe(document.getElementById('app-root'));

Preserving Web Application State on Window Transitions

One of the most common issues with TWAs in multi-window mode is state loss. On the Android OS, when an activity is resized, the system may trigger a configuration change. By default, this can cause the system to destroy and recreate the activity to load resources specific to the new layout.

For a web-based app, an activity recreation can trigger a full page reload. This resets active forms, clears unsaved input, wipes single-page application (SPA) router state, and interrupts active media playbacks. To prevent this, ensure that your native TWA wrapper configures the launcher activity to handle configuration changes programmatically. In your AndroidManifest.xml, the activity should include:

android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout"

This declaration tells Android not to restart your activity when these events occur, allowing the browser engine inside the TWA to simply adjust its viewport and process the layout change through standard CSS and JS channels.

Even with this safeguard, you should proactively persist the application state. If the user minimizes the split-screen app to the background, Android's low-memory killer may terminate the browser process to reclaim resources. Implement real-time state preservation using localStorage or IndexedDB. Keep the user's active session state, scroll positions, and form inputs serialized so that if the TWA must reload, it can restore the exact user interface state seamlessly.

Testing Multi-Window Layouts and Foldable States

Testing your TWA's responsiveness under multi-window conditions requires dedicated testing steps. You should evaluate the following scenarios before uploading your finalized AAB package to the Google Play Console:

  • Split-Screen Initialization: Open your app, press the recent apps button, tap the app icon, and select "Split screen". Verify that your layout immediately responds to the 50/50 partition.
  • Divider Dragging: Drag the partition bar to resize the app window. Check for layout jumps, overlapping text, or unwanted browser reloads.
  • Dual Screen Folding: If utilizing the Android Studio Emulator, configure an emulator profiles for foldable devices (such as the Pixel Fold) to verify how your web layout responds when moving from a folded outer cover screen to the unfolded large inner screen.

By optimizing your native manifest declarations and refining your PWA codebase to gracefully handle rapid aspect ratio changes, your TWA will feel like a deeply integrated, high-performance native application across all modern Android device formats.

Ready to ship your Android app?

Paste your PWA URL, get a signed APK and a Google Play ready AAB in minutes.

Build my app