Multi-Window, Multi-Display
intro
隨著行動裝置的演進,Android 不再只是單一螢幕、單一全螢幕應用的環境。從早期手機的單 Activity 單視窗模式,發展到今天支援 Split-Screen(分割視窗)、Picture-in-Picture(子母畫面)、Freeform 窗口、以及到多顯示器支援,Android 的 UI 架構已經演進成為一個複雜而彈性的系統。
history
- Android 7.0 (Nougat)
- 引入 Split-Screen Mode(分割螢幕),允許兩個應用同時並排顯示。
- Android 8.0 (Oreo)
- 加入 Picture-in-Picture (PiP) 模式,特別用於影片播放或導航類應用。
- Android 10
- 開始支援 多顯示器 (Multi-Display),應用可以運行在外接螢幕或虛擬顯示器。
- Android 12L / 13
- 重點改善 可折疊裝置 與 平板多視窗體驗,Task Organizer API 引入,更靈活的窗口管理能力。
系統架構
- 涉及的核心服務
- ActivityManagerService (AMS)
- 管理應用的 Activity、任務棧與生命週期,負責決定 Activity 應該放在哪個 Task 與 Display 上。
- WindowManagerService (WMS)
- 負責 Window 的排版、Z-Order、視窗層級,並處理多視窗與多螢幕環境下的視窗顯示。
- TaskOrganizer / Shell(新架構)
- 在 Android 12L 後,系統提供可客製化的任務管理方式,例如可折疊裝置的多區塊分割。
- 基本關係
多視窗 (Multi-Window)
- 基本概念
- Multi-Window 指的是在同一個 Display 上,同時顯示多個應用的 UI。這打破了早期「單一全螢幕 Activity」的限制。
- Android 提供幾種多視窗模式:
- Split-Screen(分割螢幕,從 Android 7.0 開始)
- Picture-in-Picture (PiP)(從 Android 8.0 開始)
- 一個小型浮動視窗,例如 YouTube 的子母畫面。
- Freeform Window(部分裝置開啟,例如 ChromeOS、部分廠商客製 ROM)
- 實作原理
- AMS:維護 Task 與 Window 狀態,決定 Activity 要被放在哪個 WindowingMode。
- WMS:根據 WindowingMode(SPLIT_SCREEN_PRIMARY、PICTURE_IN_PICTURE…)來繪製不同大小的視窗。
- DecorView:每個 Window 的根 View,會根據配置改變大小與佈局。
- 視窗模式 (Windowing Modes)
多螢幕 (Multi-Display)
- 基本概念
Multi-Display 指的是應用不再侷限於單一物理螢幕,而是可以運行於:
- 外接顯示器(透過 HDMI / 無線投影)。
- 虛擬顯示器(VirtualDisplay,用於錄影或鏡像)。
- 可折疊裝置的多個顯示區域。
- AMS 與 DisplayContent
AMS 中的 Task 可以被分配到不同的 DisplayContent:
- DisplayContent:WMS 中表示一個 Display 的抽象。
- RootWindowContainer:管理所有 DisplayContent。

- Activity 啟動與 Display 關聯
- 啟動 Activity 時,AMS 可以指定 ActivityOptions.setLaunchDisplayId(),將 Activity 放到特定顯示器。
- 若未指定,則依照當前使用者操作焦點,預設放到主螢幕。
- VirtualDisplay
- 開發者可透過 DisplayManager.createVirtualDisplay() 建立虛擬螢幕。
- 常見應用場景:
設計時注意事項
- 適配多視窗
- 使用 onConfigurationChanged() 偵測螢幕大小改變。
- 避免假設應用永遠全螢幕(例如硬編碼 layout)。
- 設定 android:resizeableActivity="true",允許 Activity 進入多視窗模式。
- 適配 Picture-in-Picture
<activity
android:name=".VideoActivity"
android:supportsPictureInPicture="true"
android:resizeableActivity="true" />
程式進入 PiP:
enterPictureInPictureMode(
PictureInPictureParams.Builder().build()
)
- 多螢幕支援
- 判斷目前 Activity 所在 Display:
val displayId = context.display?.displayId
val options = ActivityOptions.makeBasic()
options.launchDisplayId = display.displayId
startActivity(intent, options.toBundle())
best practice ans challenges
- 挑戰
- 生命週期更複雜:同一應用可能在多個視窗/螢幕同時存在。
- 輸入事件分發:輸入事件必須正確送到對應的 Display。
- 資源適配:螢幕大小、比例、方向不同,必須準備不同資源。
- 最佳實踐
- 使用 ConstraintLayout、Compose 等彈性佈局。
- 避免假設應用只有一個 Activity。
- 測試應用在 Split-Screen、PiP、外接螢幕的情境下。
圖表示意
-
多視窗模式

-
多螢幕架構

questions
- Android 何時引入 Multi-Window?有哪些模式?
- Android 7.0:Split-Screen。
- Android 8.0:Picture-in-Picture。
- 部分裝置:Freeform Window。
- AMS 如何管理多螢幕上的 Task?
- Task 屬於某個 DisplayContent,每個 Display 有獨立的任務棧。
- 如何讓 Activity 啟動在指定螢幕?
- 使用 ActivityOptions.setLaunchDisplayId()。
- PiP 與 Split-Screen 的差異?
- PiP 是浮動視窗,通常一個應用;Split-Screen 是螢幕分割,允許兩應用並存。
- 多螢幕輸入事件如何處理?
- InputDispatcher 根據事件來源的 DisplayId,將事件分派到對應的 Window。
summary
- Multi-Window 與 Multi-Display 是 Android 在 UI 管理上的重大演進。
- AMS/WMS 是關鍵,分別管理 Task 與 Window,並協同確保多螢幕、多視窗的正確運作。
- 開發者需要適配:
- 分割螢幕
- 子母畫面
- 外接顯示器
最佳實踐是避免假設單一全螢幕環境,以確保應用能適應未來的可折疊與多螢幕裝置。