Android 12系统源码_Window的类型

前言

了解Window的属性能够更好的理解WMS的内部原理,Window的属性有很多种,与应用开发最密切的有3种,分别是Type(Window的类型),Flag(Window的标记)和SoftInputMode(软键盘相关模式)。

Window的类型有很多种,比如应用程序窗口、系统错误窗口、输入法窗口、PopupWindow、Toast、Dialog等。总的来说Window分为三大类型,分别是Application Window(应用程序窗口)、Sub Window(子窗口)、System Window(系统窗口),每个大类型中又分很多小类型,它们都定义在WindowManager的静态内部类LayoutParams中,下面简单介绍一下Window的三大类型。

一、应用程序窗口(Type值的范围为1~99)

Activity就是一个典型的应用程序窗口,应用程序窗口包含的类型如下所示:

frameworks/base/core/java/android/view/WindowManager.java

public interface WindowManager extends ViewManager {
    public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
        //应用程序窗口的开始值
        public static final int FIRST_APPLICATION_WINDOW = 1; 
        //应用程序窗口的基础值,其他窗口的值都要大于这个值
        public static final int TYPE_BASE_APPLICATION   = 1;
        //普通的应用程序窗口类型
        public static final int TYPE_APPLICATION        = 2;
        //应用程序启动窗口类型,用户系统在应用程序窗口启动前显示的窗口
        public static final int TYPE_APPLICATION_STARTING = 3;
        //这是TYPE_APPLICATION的变体,确保WindowManager在APP展示之前绘制完成此窗口
        public static final int TYPE_DRAWN_APPLICATION = 4;
        ///应用程序窗口的开始值
        public static final int LAST_APPLICATION_WINDOW = 99;
}
}

二、子窗口(Type值的范围为1000~1999)

子窗口不能单独存在,需要依附于其他窗口才行,PopupWindow就属于子窗口。子窗口的类型定义如下所示:

frameworks/base/core/java/android/view/WindowManager.java

public interface WindowManager extends ViewManager {
    public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
       //子窗口类型初始值
       public static final int FIRST_SUB_WINDOW = 1000;
        public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;
        public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW + 1;
        public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2;
        public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3;
        public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW + 4;
        public static final int TYPE_APPLICATION_ABOVE_SUB_PANEL = FIRST_SUB_WINDOW + 5;
        //子窗口类型结束值
        public static final int LAST_SUB_WINDOW = 1999;
}
}

三、系统窗口(Type值的范围为2000~2999)

Toast、输入法窗口、系统音量条窗口、系统错误窗口都属于系统窗口。系统窗口的类型定义如下所示:

public interface WindowManager extends ViewManager {
    public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
        //系统窗口类型初始值
        public static final int FIRST_SYSTEM_WINDOW     = 2000;
        //系统状态栏,会显示在所有用户窗口中
        public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW; 
        //搜索条,会显示在所有用户窗口中
        public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1; 
        //通话界面,会显示在所有用户窗口中
        @Deprecated //use TYPE_APPLICATION_OVERLAY instead
        public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2; 
        //系统Alert,只会显示在拥有者的窗口中
        @Deprecated //use TYPE_APPLICATION_OVERLAY instead
        public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3; 
       //锁屏界面,会显示在所有用户窗口中
        public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;
        //Toast窗口,只会显示在拥有者的窗口中
        @Deprecated//use TYPE_APPLICATION_OVERLAY instead
        public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5; 
        //系统重载窗口,只会显示在拥有者的窗口中
        @Deprecated //use TYPE_APPLICATION_OVERLAY instead
        public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;
        //高权限通话窗口,会显示在所有用户窗口中
        @Deprecated //use TYPE_APPLICATION_OVERLAY instead
        public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7;
        //系统弹窗,会显示在所有用户窗口中
        public static final int TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8;
        //锁屏弹窗,会显示在所有用户窗口中
        public static final int TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9;
        //系统错误,只会显示在拥有者的窗口中
        @Deprecated//use TYPE_APPLICATION_OVERLAY instead
        public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;
        //输入法,只会显示在拥有者的窗口中
        public static final int TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11;
        //输入法弹窗,只会显示在拥有者的窗口中
        public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12;
        //壁纸,只会显示在拥有者的窗口中
        public static final int TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13;
        //状态栏控制面板,会显示在所有用户窗口中
        public static final int TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14;
        //安全系统重载,只会显示在拥有者的窗口中
        public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15;
       //拖拽,只会显示在拥有者的窗口中
        public static final int TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16;
       //状态栏子控制面板,会显示在所有用户窗口中
        public static final int TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17;
        //焦点,会显示在所有用户窗口中
        public static final int TYPE_POINTER = FIRST_SYSTEM_WINDOW+18;
        //系统导航栏,会显示在所有用户窗口中
       public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;
        //音量,会显示在所有用户窗口中
        public static final int TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20;
        //Boot进度条,会显示在所有用户窗口中
        public static final int TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21;
        //当状态栏被隐藏后的自定义输入事件,会显示在所有用户窗口中
        public static final int TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW+22;
       //导航栏控制面板,会显示在所有用户窗口中
        public static final int TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24;
        //显示屏重载窗口,会显示在所有用户窗口中
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public static final int TYPE_DISPLAY_OVERLAY = FIRST_SYSTEM_WINDOW+26;
        //放大器窗口,会显示在所有用户窗口中
        public static final int TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW+27;
        //提示窗口上的私有虚拟显示
        public static final int TYPE_PRIVATE_PRESENTATION = FIRST_SYSTEM_WINDOW+30;
        //窗口的声音交互层
        public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;

        public static final int TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32;
        //启动窗口的声音交互层
        public static final int TYPE_VOICE_INTERACTION_STARTING = FIRST_SYSTEM_WINDOW+33;
        //调整分屏模式下每个窗口大小的分割线
        public static final int TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW+34;
        //快捷设置弹窗
        public static final int TYPE_QS_DIALOG = FIRST_SYSTEM_WINDOW+35;
        //截屏,会显示在所有用户窗口中
        public static final int TYPE_SCREENSHOT = FIRST_SYSTEM_WINDOW + 36;

        public static final int TYPE_PRESENTATION = FIRST_SYSTEM_WINDOW + 37;
        //很多废弃的系统弹窗类型都可以使用这个进行替换,只会显示在拥有者的窗口中
        public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38;
        //会显示在所有用户窗口中
        public static final int TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 39;
        //会显示在所有用户窗口中
        public static final int TYPE_NOTIFICATION_SHADE = FIRST_SYSTEM_WINDOW + 40;
        //会显示在所有用户窗口中
        public static final int TYPE_STATUS_BAR_ADDITIONAL = FIRST_SYSTEM_WINDOW + 41;
        //系统窗口类型的结束值
        public static final int LAST_SYSTEM_WINDOW      = 2999;
}
}

四 窗口层级

1、决定窗口显示层级的关键代码如下所示。

frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java

public interface WindowManagerPolicy extends WindowManagerPolicyConstants {

    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow,
            boolean roundedCornerOverlay) {
        // Always put the rounded corner layer to the top most.
        if (roundedCornerOverlay && canAddInternalSystemWindow) {
            return getMaxWindowLayer();
        }
        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
            return APPLICATION_LAYER;
        }

        switch (type) {
            case TYPE_WALLPAPER:
                // wallpaper is at the bottom, though the window manager may move it.
                return  1;
            case TYPE_PRESENTATION:
            case TYPE_PRIVATE_PRESENTATION:
            case TYPE_DOCK_DIVIDER:
            case TYPE_QS_DIALOG:
            case TYPE_PHONE:
                return  3;
            case TYPE_SEARCH_BAR:
            case TYPE_VOICE_INTERACTION_STARTING:
                return  4;
            case TYPE_VOICE_INTERACTION:
                // voice interaction layer is almost immediately above apps.
                return  5;
            case TYPE_INPUT_CONSUMER:
                return  6;
            case TYPE_SYSTEM_DIALOG:
                return  7;
            case TYPE_TOAST:
                // toasts and the plugged-in battery thing
                return  8;
            case TYPE_PRIORITY_PHONE:
                // SIM errors and unlock.  Not sure if this really should be in a high layer.
                return  9;
            case TYPE_SYSTEM_ALERT:
                // like the ANR / app crashed dialogs
                // Type is deprecated for non-system apps. For system apps, this type should be
                // in a higher layer than TYPE_APPLICATION_OVERLAY.
                return  canAddInternalSystemWindow ? 13 : 10;
            case TYPE_APPLICATION_OVERLAY:
                return  12;
            case TYPE_INPUT_METHOD:
                // on-screen keyboards and other such input method user interfaces go here.
                return  15;
            case TYPE_INPUT_METHOD_DIALOG:
                // on-screen keyboards and other such input method user interfaces go here.
                return  16;
            case TYPE_STATUS_BAR:
                return  17;//状态栏
            case TYPE_STATUS_BAR_ADDITIONAL:
                return  18;
            case TYPE_NOTIFICATION_SHADE:
                return  19;
            case TYPE_STATUS_BAR_SUB_PANEL:
                return  20;
            case TYPE_KEYGUARD_DIALOG:
                return  21;
            case TYPE_VOLUME_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  22;
            case TYPE_SYSTEM_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  canAddInternalSystemWindow ? 23 : 11;
            case TYPE_NAVIGATION_BAR:
                // the navigation bar, if available, shows atop most things
                return  24;
            case TYPE_NAVIGATION_BAR_PANEL:
                // some panels (e.g. search) need to show on top of the navigation bar
                return  25;
            case TYPE_SCREENSHOT:
                // screenshot selection layer shouldn't go above system error, but it should cover
                // navigation bars at the very least.
                return  26;
            case TYPE_SYSTEM_ERROR:
                // system-level error dialogs
                return  canAddInternalSystemWindow ? 27 : 10;
            case TYPE_MAGNIFICATION_OVERLAY:
                // used to highlight the magnified portion of a display
                return  28;
            case TYPE_DISPLAY_OVERLAY:
                // used to simulate secondary display devices
                return  29;
            case TYPE_DRAG:
                // the drag layer: input for drag-and-drop is associated with this window,
                // which sits above all other focusable windows
                return  30;
            case TYPE_ACCESSIBILITY_OVERLAY:
                // overlay put by accessibility services to intercept user interaction
                return  31;
            case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
                return 32;
            case TYPE_SECURE_SYSTEM_OVERLAY:
                return  33;
            case TYPE_BOOT_PROGRESS:
                return  34;
            case TYPE_POINTER:
                // the (mouse) pointer layer
                return  35;
            default:
                Slog.e("WindowManager", "Unknown window type: " + type);
                return 3;
        }
    }
 }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值