Android Freeform模式

Android N引入了Multi-Window, Freeform自由窗口模式是其中的一種。自由窗口模式下可以實現窗口的可以自由縮放,自由移動。

1. Freeform功能開啓

Android原生版本沒有開啓Freeform功能,ActivityManagerService中定義是否支持freeform模式,可以看到有兩種方式來開啓Freeform,一種是通過system feature定義,一種是通過setting增加開關啓動。


如果通過system feature定義,可以查看AOSP已經定義的Feature配置文件:

frameworks/native/data/etc/android.software.freeform_window_management.xml

只需要把此文件push到手機的system/etc/permissions/目錄下,開機時PMS會通過的讀取此目錄下xml配置開啓freeform這個feature.

2. Freeform模式主要功能實現

要支持Freeform自由窗口模式,主要有如下一些邏輯支持:

A)定義特有的freeform stack,所有的freeform模式的Activity會在特定的Freeform stack啓動。

B)  爲Freeform窗口添加特殊的layout, 用於控制窗口最大化,關閉以及拖動等功能。

C)爲Freeform提供一個控制窗口初始化位置和大小的類

D)  爲Freeform提供可以控制窗口移動和縮放處理的類


2.1 Freeform stack

增加了Freeform特有的stack


已經定義了freeform的stack,那要如何讓應用進入Freeform stack?

AMS提供了API支持Task在不同stack間移動, 將task移動到FREEFORM_WORKSPACE_STACK_ID,則應用進入自由窗口模式:

public void moveTaskToStack(int taskId, int stackId, boolean toTop)

2.2 Freeform窗口關閉最小化控制

爲Freeform增加了一個特殊的Layout: DecorCaptionView, 直接掛在DecorView下
framework/base/core/res/res/layout/decor_caption.xml


關閉&退出按鈕的實現在Activity類中實現,DecorCaptionView通過兩個Callback將關閉及退出的操作轉發給Activity.
具體由Activity類實現了關閉及退出的操作。

2.3 Freeform窗口默認大小及位置

Freeform窗口的默認大小及佈局由LaunchingTaskPositioner控制,啓動Activity時通過設定Default Bounds來設置窗口初始化大小及位置。

AOSP默認Freeform窗口大小爲 屏幕的1/2,位置屏幕中間位置。如果啓動了多個窗口,通過位移錯開排布。

2.4 窗口移動及縮放

窗口的移動主要由TaskPostioner處理, 開始移動時先記下初始位置,註冊Input事件監聽. 移動過程中根據Input更新窗口Bounds達到移動窗口的目標。


對於Freeform窗口的縮放,AOSP默認支持橫向/縱向/對角三種拉伸方式,窗口縮放 與窗口移動一樣由TaskPositioner處理
整個流程與remove類似。由於窗口縮放後,config發生變化,對於某些採用sw/ w/ h/resolution等定義的資源有影響,可能會觸發重新加載資源。


3. Debug技巧

通過am stack move-task命令將stack移到freeform stack.

首先可以通過am命令來查看stack及task信息


然後用am stack move-task的命令移動stack, 這樣窗口就進入了freeform自由窗口模式。

某些應用可能設置了不能resizeable, 需要使用adb shell am task resizeable來設置resizeable屬性,這樣窗口才能自由拖動和縮放。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章