Android Window Layer层级关系

在将Android window Layer层级关系之前,我们先来直观的看看是什么样的:

adb shell dumpsys SurfaceFlinger

可以看到类似这样的输出:

Display 0 HWC layers:
-------------------------------------------------------------------------------
 Layer name
           Z |  Comp Type |   Disp Frame (LTRB) |          Source Crop (LTRB)
-------------------------------------------------------------------------------
xxx xxx#0
      231000 |     Client |    0 1538  565 1578 |    0.0    0.0  565.0  426.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xxx xxx#0
      241000 |     Client |    0 1180  565 1744 |    0.0    0.0  565.0  564.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xxx xxx#0
      241005 |     Client |    0 1568  130 1578 |    0.0    0.0  130.0  220.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xxx xxx#0
      241010 |     Client |  860 1568  565 1578 |    0.0    0.0  130.0  220.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xxx xxx control#0
      241015 |     Client |    0 1180  130 1744 |    0.0    0.0  130.0  564.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xxx  xxx #0
      241020 |     Client |  860 1180  565 1744 |    0.0    0.0  130.0  564.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

这个输出包含了,Layer层级,Layer 画面的width, height 信息,要理解Layer 的层级关系,我们先要了解三个东西:WindowType, Z-Order, Layer

1.WindowType

在 WindowManager.java 中定义了Window的类型,这个类型引用 也是应用开发过程中直接使用的类型,主要分成三大类:
Application windows(应用窗口): 1~99
Sub-windows(子窗口): 1000~1999
System windows(系统窗口): 2000~2999

注意:

网上有很多说法,系统窗口 > 子窗口 > 应用窗口,从数值上来说是正确的,但是如果说 Window Layer的层级关系,这个说法就是错误的,举个很简单的例子,壁纸层 属于系统窗口管理,但是Window Layer的层级关系 却是最底端;WindowType 的值划分是为了更好的管理Window的类别、权限、依赖关系,和实际的Window Layer层级并没有关系。

2. Z-Order

可以去查一下这个词汇的含义,这个词汇一般出现在产品,UX设计过程中,而这个值的定义才是产品意义上的界面层级关系;Android WindowManagerPolicy中也给出了WindowType 和 Z-Order的对应关系:

    /**
     * Returns the layer assignment for the window type. Allows you to control how different
     * kinds of windows are ordered on-screen.
     *
     * @param type The type of window being assigned.
     * @param canAddInternalSystemWindow If the owner window associated with the type we are
     *        evaluating can add internal system windows. I.e they have
     *        {@link permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
     *        types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
     *        can be assigned layers greater than the layer for
     *        {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
     *        layers would be lesser.
     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
     */
    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_SUB_PANEL:
                return  17;
            case TYPE_STATUS_BAR:
                return  18;
            case TYPE_STATUS_BAR_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;
        }
    }

可以看出Android8.0 Z-Order 定义了33 层, 相信看到这个兑换关系会解决你很多疑惑,到了这一层还是跟我们一开始看到的Layer 关系对不上。还有一层Z-Order 如何跟Surface Layer 进行对应?

3. Layer

Android 画面内容输出,是通过SurfaceFlinger 进行画面的合成、输出的,直接关联的就是Layer
Framework中计算Layer 的公式为:Layer = Z-Order * 10000 + 1000 :

getWindowLayerFromTypeLw() * WindowManagerService.TYPE_LAYER_MULTIPLIER + WindowManagerService.TYPE_LAYER_OFFSET

相同Layer 会根据添加的顺序,加上offset 值。

你可能感兴趣的:(Android Window Layer层级关系)