文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android WindowManger的层级分析详解

2024-04-02 19:55

关注

一. Window 分类

  • 应用 WindowApplicationWindow: 对应一个 Acitivity
  • 子 Window    SubWindow:不能单独存在,需要依附在特定的父 Window 中,比如常见的一些 Dialog 就是一个子 Window
  • 系统 Window SystemWindow:需要声明权限才能创建的 Window,比如 Toast 和系统状态栏都是系统 Window

二. Window层级

Window 是分层的,每个 Window 都有对应的 z-ordered,层级大的会覆盖在层级小的 Window 上面,这和 HTML 中的 z-index 概念是完全一致的。

在三种 Window 中,每一种Window的层级范围也是不同的,如下:

应用Window    1~99

子Window        1000~1999

系统Window    2000~2999

这些层级范围对应着 WindowManager.LayoutParams type 参数,如果想要 Window 位于所有 Window 的最顶层,那么采用较大的层级即可,很显然系统 Window 的层级是最大的,当我们采用系统层级时,需要声明权限。

(1)应用程序窗口:


package android.view;
public interface WindowManager
        
        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;
 
        
        public static final int TYPE_DRAWN_APPLICATION = 4;
 
        
        public static final int LAST_APPLICATION_WINDOW = 99;

(2)子窗口:


package android.view;
public interface WindowManager
        
        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;
 
        
        @UnsupportedAppUsage
        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;

(3)系统窗口:


package android.view;
public interface WindowManager
        
        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
        public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
 
        
        @Deprecated
        public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
 
        
        public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;
 
        
        @Deprecated
        public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;
 
        
        @Deprecated
        public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;
 
        
        @Deprecated
        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
        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;
 
        
        @UnsupportedAppUsage
        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;
 
        
        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_DREAM = FIRST_SYSTEM_WINDOW+23;
 
        
        public static final int TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24;
 
        
        @UnsupportedAppUsage
        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 LAST_SYSTEM_WINDOW      = 2999;

 窗口显示顺序:
Type 值越大层级越高,Type 值大的覆盖 Type 值小的,这只是一般规律。

(三)如何真正查看 Window 的优先级


/frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java
    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
        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:
                return  APPLICATION_LAYER;
            case TYPE_DOCK_DIVIDER:
                return  APPLICATION_LAYER;
            case TYPE_QS_DIALOG:
                return  APPLICATION_LAYER;
            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
                return  canAddInternalSystemWindow ? 11 : 10;
            case TYPE_APPLICATION_OVERLAY:
                return  12;
            case TYPE_DREAM:
                // used for Dreams (screensavers with TYPE_DREAM windows)
                return  13;
            case TYPE_INPUT_METHOD:
                // on-screen keyboards and other such input method user interfaces go here.
                return  14;
            case TYPE_INPUT_METHOD_DIALOG:
                // on-screen keyboards and other such input method user interfaces go here.
                return  15;
            case TYPE_STATUS_BAR:
                return  17;
            case TYPE_STATUS_BAR_PANEL:
                return  18;
            case TYPE_STATUS_BAR_SUB_PANEL:
                return  19;
            case TYPE_KEYGUARD_DIALOG:
                return  20;
            case TYPE_VOLUME_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  21;
            case TYPE_SYSTEM_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  canAddInternalSystemWindow ? 22 : 11;
            case TYPE_NAVIGATION_BAR:
                // the navigation bar, if available, shows atop most things
                return  23;
            case TYPE_NAVIGATION_BAR_PANEL:
                // some panels (e.g. search) need to show on top of the navigation bar
                return  24;
            case TYPE_SCREENSHOT:
                // screenshot selection layer shouldn't go above system error, but it should cover
                // navigation bars at the very least.
                return  25;
            case TYPE_SYSTEM_ERROR:
                // system-level error dialogs
                return  canAddInternalSystemWindow ? 26 : 10;
            case TYPE_MAGNIFICATION_OVERLAY:
                // used to highlight the magnified portion of a display
                return  27;
            case TYPE_DISPLAY_OVERLAY:
                // used to simulate secondary display devices
                return  28;
            case TYPE_DRAG:
                // the drag layer: input for drag-and-drop is associated with this window,
                // which sits above all other focusable windows
                return  29;
            case TYPE_ACCESSIBILITY_OVERLAY:
                // overlay put by accessibility services to intercept user interaction
                return  30;
            case TYPE_SECURE_SYSTEM_OVERLAY:
                return  31;
            case TYPE_BOOT_PROGRESS:
                return  32;
            case TYPE_POINTER:
                // the (mouse) pointer layer
                return  33;
            default:
                Slog.e("WindowManager", "Unknown window type: " + type);
                return APPLICATION_LAYER;
        }
    }

 以上返回的是除 Application 外的 Window 的层级,在开发系统应用时可以选择一种开发自己的 Window.

(四) 层级高低具体分析(对比Toast以及软键盘)


低于toast--->盖不住toast
低于软键盘--->盖不住软键盘
依附Activity使用--->is your activity running?
 public static int getWindowType(int num) {
        switch (num) {
            case 1:
                return WindowManager.LayoutParams.TYPE_PHONE;//低于toast  低于软键盘
            case 2:
                return WindowManager.LayoutParams.TYPE_SEARCH_BAR;//低于toast  低于软键盘
            case 3:
                return WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;//低于toast  低于软键盘
            case 4:
                return WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;//高于toast  低于软键盘
            case 5:
                return WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;//高于toast  低于软键盘
            case 6:
                return WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;//高于toast  盖住键盘
            case 7:
                return WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;//高于toast    低于软键盘
            case 8:
                return WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;//高于toast  低于软键盘
            case 9:
                return WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;//高于toast  高于软键盘
            case 10:
                return WindowManager.LayoutParams.TYPE_STATUS_BAR;//高于toast  高于软键盘(键盘会把透明view顶起)
            case 11:
                return WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;//高于toast  高于软键盘(键盘会把透明view顶起)
            case 12:
                return WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;//低于下级页面
            case 13:
                return WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;//is your activity running?
            case 14:
                return WindowManager.LayoutParams.TYPE_BASE_APPLICATION;// is your activity running?
            case 15:
                return WindowManager.LayoutParams.TYPE_APPLICATION;// is your activity running?
            case 16:
                return WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;// is your activity running?
            case 17:
                return WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;// is your activity running?
            case 18:
                return WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;// is your activity running?
            case 19:
                return WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;// is your activity running?
            case 20:
                return WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;// is your activity running?
            case 21:
                return WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;// is your activity running?
            case 22:
                return WindowManager.LayoutParams.TYPE_WALLPAPER;// is your activity running?
            case 23:
                return WindowManager.LayoutParams.TYPE_TOAST;// is your activity running?
            case 24:
                return WindowManager.LayoutParams.TYPE_INPUT_METHOD;//is your activity running?
            case 25:
                return WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;//permission denied for window type 2030
            default:
                return 0;
        }
    }

(五)如何定制系统层级

改变层级关系需要改写 getWindowLayerFromTypeLw 的 switch 顺序结构和返回值
如果需要更改一些 Window 的行为,需要修改
/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

到此这篇关于Android WindowManger的层级分析详解的文章就介绍到这了,更多相关Android WindowManger的层级分析内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯