千家信息网

Android中WindowManger的层级分析

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这期内容当中小编将会给大家带来有关Android中WindowManger的层级分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一. Window 分类应用 Wi
千家信息网最后更新 2025年01月19日Android中WindowManger的层级分析

这期内容当中小编将会给大家带来有关Android中WindowManger的层级分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

一. 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.LayoutParamstype 参数,如果想要 Window 位于所有 Window 的最顶层,那么采用较大的层级即可,很显然系统 Window 的层级是最大的,当我们采用系统层级时,需要声明权限。

(1)应用程序窗口:

package android.view;public interface WindowManager        /**         * Start of window types that represent normal application windows.         */        public static final int FIRST_APPLICATION_WINDOW = 1;         /**         * Window type: an application window that serves as the "base" window         * of the overall application; all other application windows will         * appear on top of it.         * In multiuser systems shows only on the owning user's window.         */        public static final int TYPE_BASE_APPLICATION   = 1;         /**         * Window type: a normal application window.  The {@link #token} must be         * an Activity token identifying who the window belongs to.         * In multiuser systems shows only on the owning user's window.         */        public static final int TYPE_APPLICATION        = 2;         /**         * Window type: special application window that is displayed while the         * application is starting.  Not for use by applications themselves;         * this is used by the system to display something until the         * application can show its own windows.         * In multiuser systems shows on all users' windows.         */        public static final int TYPE_APPLICATION_STARTING = 3;         /**         * Window type: a variation on TYPE_APPLICATION that ensures the window         * manager will wait for this window to be drawn before the app is shown.         * In multiuser systems shows only on the owning user's window.         */        public static final int TYPE_DRAWN_APPLICATION = 4;         /**         * End of types of application windows.         */        public static final int LAST_APPLICATION_WINDOW = 99;

(2)子窗口:

package android.view;public interface WindowManager        /**         * Start of types of sub-windows.  The {@link #token} of these windows         * must be set to the window they are attached to.  These types of         * windows are kept next to their attached window in Z-order, and their         * coordinate space is relative to their attached window.         */        public static final int FIRST_SUB_WINDOW = 1000;         /**         * Window type: a panel on top of an application window.  These windows         * appear on top of their attached window.         */        public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;         /**         * Window type: window for showing media (such as video).  These windows         * are displayed behind their attached window.         */        public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW + 1;         /**         * Window type: a sub-panel on top of an application window.  These         * windows are displayed on top their attached window and any         * {@link #TYPE_APPLICATION_PANEL} panels.         */        public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2;         /** Window type: like {@link #TYPE_APPLICATION_PANEL}, but layout         * of the window happens as that of a top-level window, not         * as a child of its container.         */        public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3;         /**         * Window type: window for showing overlays on top of media windows.         * These windows are displayed between TYPE_APPLICATION_MEDIA and the         * application window.  They should be translucent to be useful.  This         * is a big ugly hack so:         * @hide         */        @UnsupportedAppUsage        public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW + 4;         /**         * Window type: a above sub-panel on top of an application window and it's         * sub-panel windows. These windows are displayed on top of their attached window         * and any {@link #TYPE_APPLICATION_SUB_PANEL} panels.         * @hide         */        public static final int TYPE_APPLICATION_ABOVE_SUB_PANEL = FIRST_SUB_WINDOW + 5;         /**         * End of types of sub-windows.         */        public static final int LAST_SUB_WINDOW = 1999;

(3)系统窗口:

package android.view;public interface WindowManager        /**         * Start of system-specific window types.  These are not normally         * created by applications.         */        public static final int FIRST_SYSTEM_WINDOW     = 2000;         /**         * Window type: the status bar.  There can be only one status bar         * window; it is placed at the top of the screen, and all other         * windows are shifted down so they are below it.         * In multiuser systems shows on all users' windows.         */        public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW;         /**         * Window type: the search bar.  There can be only one search bar         * window; it is placed at the top of the screen.         * In multiuser systems shows on all users' windows.         */        public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1;         /**         * Window type: phone.  These are non-application windows providing         * user interaction with the phone (in particular incoming calls).         * These windows are normally placed above all applications, but behind         * the status bar.         * In multiuser systems shows on all users' windows.         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.         */        @Deprecated        public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;         /**         * Window type: system window, such as low power alert. These windows         * are always on top of application windows.         * In multiuser systems shows only on the owning user's window.         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.         */        @Deprecated        public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;         /**         * Window type: keyguard window.         * In multiuser systems shows on all users' windows.         * @removed         */        public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;         /**         * Window type: transient notifications.         * In multiuser systems shows only on the owning user's window.         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.         */        @Deprecated        public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;         /**         * Window type: system overlay windows, which need to be displayed         * on top of everything else.  These windows must not take input         * focus, or they will interfere with the keyguard.         * In multiuser systems shows only on the owning user's window.         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.         */        @Deprecated        public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;         /**         * Window type: priority phone UI, which needs to be displayed even if         * the keyguard is active.  These windows must not take input         * focus, or they will interfere with the keyguard.         * In multiuser systems shows on all users' windows.         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.         */        @Deprecated        public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7;         /**         * Window type: panel that slides out from the status bar         * In multiuser systems shows on all users' windows.         */        public static final int TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8;         /**         * Window type: dialogs that the keyguard shows         * In multiuser systems shows on all users' windows.         */        public static final int TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9;         /**         * Window type: internal system error windows, appear on top of         * everything they can.         * In multiuser systems shows only on the owning user's window.         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.         */        @Deprecated        public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;         /**         * Window type: internal input methods windows, which appear above         * the normal UI.  Application windows may be resized or panned to keep         * the input focus visible while this window is displayed.         * In multiuser systems shows only on the owning user's window.         */        public static final int TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11;         /**         * Window type: internal input methods dialog windows, which appear above         * the current input method window.         * In multiuser systems shows only on the owning user's window.         */        public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12;         /**         * Window type: wallpaper window, placed behind any window that wants         * to sit on top of the wallpaper.         * In multiuser systems shows only on the owning user's window.         */        public static final int TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13;         /**         * Window type: panel that slides out from over the status bar         * In multiuser systems shows on all users' windows.         */        public static final int TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14;         /**         * Window type: secure system overlay windows, which need to be displayed         * on top of everything else.  These windows must not take input         * focus, or they will interfere with the keyguard.         *         * This is exactly like {@link #TYPE_SYSTEM_OVERLAY} except that only the         * system itself is allowed to create these overlays.  Applications cannot         * obtain permission to create secure system overlays.         *         * In multiuser systems shows only on the owning user's window.         * @hide         */        @UnsupportedAppUsage        public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15;         /**         * Window type: the drag-and-drop pseudowindow.  There is only one         * drag layer (at most), and it is placed on top of all other windows.         * In multiuser systems shows only on the owning user's window.         * @hide         */        public static final int TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16;         /**         * Window type: panel that slides out from over the status bar         * In multiuser systems shows on all users' windows. These windows         * are displayed on top of the stauts bar and any {@link #TYPE_STATUS_BAR_PANEL}         * windows.         * @hide         */        public static final int TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17;         /**         * Window type: (mouse) pointer         * In multiuser systems shows on all users' windows.         * @hide         */        public static final int TYPE_POINTER = FIRST_SYSTEM_WINDOW+18;         /**         * Window type: Navigation bar (when distinct from status bar)         * In multiuser systems shows on all users' windows.         * @hide         */        public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;         /**         * Window type: The volume level overlay/dialog shown when the user         * changes the system volume.         * In multiuser systems shows on all users' windows.         * @hide         */        public static final int TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20;         /**         * Window type: The boot progress dialog, goes on top of everything         * in the world.         * In multiuser systems shows on all users' windows.         * @hide         */        public static final int TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21;         /**         * Window type to consume input events when the systemUI bars are hidden.         * In multiuser systems shows on all users' windows.         * @hide         */        public static final int TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW+22;         /**         * Window type: Dreams (screen saver) window, just above keyguard.         * In multiuser systems shows only on the owning user's window.         * @hide         */        public static final int TYPE_DREAM = FIRST_SYSTEM_WINDOW+23;         /**         * Window type: Navigation bar panel (when navigation bar is distinct from status bar)         * In multiuser systems shows on all users' windows.         * @hide         */        public static final int TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24;         /**         * Window type: Display overlay window.  Used to simulate secondary display devices.         * In multiuser systems shows on all users' windows.         * @hide         */        @UnsupportedAppUsage        public static final int TYPE_DISPLAY_OVERLAY = FIRST_SYSTEM_WINDOW+26;         /**         * Window type: Magnification overlay window. Used to highlight the magnified         * portion of a display when accessibility magnification is enabled.         * In multiuser systems shows on all users' windows.         * @hide         */        public static final int TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW+27;         /**         * Window type: Window for Presentation on top of private         * virtual display.         */        public static final int TYPE_PRIVATE_PRESENTATION = FIRST_SYSTEM_WINDOW+30;         /**         * Window type: Windows in the voice interaction layer.         * @hide         */        public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;         /**         * Window type: Windows that are overlaid only by a connected {@link         * android.accessibilityservice.AccessibilityService} for interception of         * user interactions without changing the windows an accessibility service         * can introspect. In particular, an accessibility service can introspect         * only windows that a sighted user can interact with which is they can touch         * these windows or can type into these windows. For example, if there         * is a full screen accessibility overlay that is touchable, the windows         * below it will be introspectable by an accessibility service even though         * they are covered by a touchable window.         */        public static final int TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32;         /**         * Window type: Starting window for voice interaction layer.         * @hide         */        public static final int TYPE_VOICE_INTERACTION_STARTING = FIRST_SYSTEM_WINDOW+33;         /**         * Window for displaying a handle used for resizing docked stacks. This window is owned         * by the system process.         * @hide         */        public static final int TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW+34;         /**         * Window type: like {@link #TYPE_APPLICATION_ATTACHED_DIALOG}, but used         * by Quick Settings Tiles.         * @hide         */        public static final int TYPE_QS_DIALOG = FIRST_SYSTEM_WINDOW+35;         /**         * Window type: shares similar characteristics with {@link #TYPE_DREAM}. The layer is         * reserved for screenshot region selection. These windows must not take input focus.         * @hide         */        public static final int TYPE_SCREENSHOT = FIRST_SYSTEM_WINDOW + 36;         /**         * Window type: Window for Presentation on an external display.         * @see android.app.Presentation         * @hide         */        public static final int TYPE_PRESENTATION = FIRST_SYSTEM_WINDOW + 37;         /**         * Window type: Application overlay windows are displayed above all activity windows         * (types between {@link #FIRST_APPLICATION_WINDOW} and {@link #LAST_APPLICATION_WINDOW})         * but below critical system windows like the status bar or IME.         * 

* The system may change the position, size, or visibility of these windows at anytime * to reduce visual clutter to the user and also manage resources. *

* Requires {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission. *

* The system will adjust the importance of processes with this window type to reduce the * chance of the low-memory-killer killing them. *

* In multi-user systems shows only on the owning user's screen. */ public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38; /** * End of types of system windows. */ 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的层级分析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

0