本文基于android9.0来写的。
一、产品需求:如下图,类似mac的桌面系统
(1)区域1是系统标题栏。
(2)区域2是长显示的窗口。
(3)区域3 普通app显示的窗口。
(4) 区域4 也是一个上显示的窗口,主要用于应用的点击启动。
二、下图是根据Android系统特性画的草图:
(1)区域1是系统statusBar。
(2)区域2是长显示的窗口,用WindowMananger添加的窗口。
(3)区域3 普通app显示的窗口,定制系统默认窗口大小,定位至区域3。
(4) 区域4 也是一个长显示的窗口,同样是用WindowMananger添加的窗口。
三、主要实现思路:通过freefrom 和添加悬浮window来实现。因为app只有在freeform模式才能任意定制多窗口大小和位置。
1、区域1无需改动,还是采用系统默认stausBar。
2、修改famework AMS ,以freeform模式启动Launcher。修改HOME的的区域为上图区域3。
3、Lancher启动时,同时启动两个两个service, 然后通过WindowManger来添加区域2和区域4。
4、区域4 的Icon点击以freeform模式启动其他APP。在framework拦截启动APP的入口,以freeform模式启动,同时设置窗口大小和位置(区域3)。
四、最终实现的demo如下:
五、具体实现方法如下:
1、开启freeform
google 默认freeform是关闭的,如果要测试需要手动开启。
配置config_freeformWindowManagement
WORKING_DIRECTORY/frameworks/base/core/res/res/values/config.xml
如下,将config_freeformWindowManagement配置为true
WORKING_DIRECTORY/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private void retrieveSettings() {
final ContentResolver resolver = mContext.getContentResolver();
//获取是否支持freeform
final boolean freeformWindowManagement =
mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
|| Settings.Global.getInt(
resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
由上面代码可以看出有两种方法可以开启freeform
(1) Settings 设置开启的属性
WORKING_DIRECTORY/frameworks/base/core/java/android/provider/Settings.java
/**
* Whether any activity can be resized. When this is true, any
* activity, regardless of manifest values, can be resized for multi-window.
* (0 = false, 1 = true)
* @hide
*/
public static final String DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES
= "force_resizable_activities";
/**
* Whether to enable experimental freeform support for windows.
* @hide
*/
public static final String DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT
= "enable_freeform_support";
这个用命令就可以开启:
adb shell settings put global enable_freeform_support 1
adb shell settings put global force_resizable_activities 1
如果要在framework中默认开启,可以这样:
private void retrieveSettings() {
final ContentResolver resolver = mContext.getContentResolver();
//简单粗暴开启,哈哈
Settings.Global.putInt(resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 1);
Settings.Global.putInt(resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVIT