Android Freeform模式

Android N引入了Multi-Window, Freeform自由窗口模式是其中的一种。自由窗口模式下可以实现窗口的可以自由缩放,自由移动。

1. Freeform功能开启

Android原生版本没有开启Freeform功能,ActivityManagerService中定义是否支持freeform模式,可以看到有两种方式来开启Freeform,一种是通过system feature定义,一种是通过setting增加开关启动。

Android Freeform模式_第1张图片


如果通过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

Android Freeform模式_第2张图片

已经定义了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

Android Freeform模式_第3张图片


关闭&退出按钮的实现在Activity类中实现,DecorCaptionView通过两个Callback将关闭及退出的操作转发给Activity.
具体由Activity类实现了关闭及退出的操作。

Android Freeform模式_第4张图片

2.3 Freeform窗口默认大小及位置

Freeform窗口的默认大小及布局由LaunchingTaskPositioner控制,启动Activity时通过设定Default Bounds来设置窗口初始化大小及位置。

Android Freeform模式_第5张图片

AOSP默认Freeform窗口大小为 屏幕的1/2,位置屏幕中间位置。如果启动了多个窗口,通过位移错开排布。

2.4 窗口移动及缩放

窗口的移动主要由TaskPostioner处理, 开始移动时先记下初始位置,注册Input事件监听. 移动过程中根据Input更新窗口Bounds达到移动窗口的目标。

Android Freeform模式_第6张图片

对于Freeform窗口的缩放,AOSP默认支持横向/纵向/对角三种拉伸方式,窗口缩放 与窗口移动一样由TaskPositioner处理
整个流程与remove类似。由于窗口缩放后,config发生变化,对于某些采用sw/ w/ h/resolution等定义的资源有影响,可能会触发重新加载资源。

Android Freeform模式_第7张图片

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属性,这样窗口才能自由拖动和缩放。


你可能感兴趣的:(Android)