文章目录

    • 1、简介
    • 2、启动
    • 3、addView
    • 4、Layer
    • 5、WindowState
    • 6、WindowToken
    • 7、Session
    • 8、Surface

1、简介

WindowManagerService(WMS)是Android中很重要的一个服务,主要的职责是与ActivityManagerService(AMS)交互以管理Window,与InputManagerService(IMS)交互以派发事件。分析WMS,先从下面的类图开始吧,看看相关的类都有哪些,主要的类包括WindowManagerService、WindowManagerImpl、PhoneWindowManager、WindowManagerGlobal、ViewRootImpl等。

2、启动

WMS是在SystemServer中启动的,下面的时序图展示了WMS及AMS、IMS的启动过程,以及它们是如何建立联系的。

3、addView

addView是一个常用的方法,流程图如下。从WindowManagerImpl开始,经WindowManagerGlobal、ViewRootImpl、Session,最后到WindowManagerService结束。在WMS的addWindow中,首先要检查权限,然后通过WindowToken、WindowState完成。

4、Layer

Window有三种类型,Application Window、Sub Window和System Window,这些Window有不同的Type,用int表示, Application Window从1到99,Sub Window从1000到1999,System Window从2000到2999,它们在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;        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;        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;        public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;        public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;        public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;        public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;        public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;        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;        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;        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;        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;

Window都有自己的Layer,即z-order,表示在屏幕上显示的层级顺序。Application Window都属于Application Layer,值为2,其它的则不同,它们在WindowManagerPolicy可以找到,代码如下。

    int APPLICATION_LAYER = 2;    int APPLICATION_MEDIA_SUBLAYER = -2;    int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;    int APPLICATION_PANEL_SUBLAYER = 1;    int APPLICATION_SUB_PANEL_SUBLAYER = 2;    int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;    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;        }    }    default int getSubWindowLayerFromTypeLw(int type) {        switch (type) {            case TYPE_APPLICATION_PANEL:            case TYPE_APPLICATION_ATTACHED_DIALOG:                return APPLICATION_PANEL_SUBLAYER;            case TYPE_APPLICATION_MEDIA:                return APPLICATION_MEDIA_SUBLAYER;            case TYPE_APPLICATION_MEDIA_OVERLAY:                return APPLICATION_MEDIA_OVERLAY_SUBLAYER;            case TYPE_APPLICATION_SUB_PANEL:                return APPLICATION_SUB_PANEL_SUBLAYER;            case TYPE_APPLICATION_ABOVE_SUB_PANEL:                return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER;        }        Slog.e("WindowManager", "Unknown sub-window type: " + type);        return 0;    }

Window的Layer,上面只是从1开始逐个递增1,在转换为z-order时,还要进行转换,首先乘10000,然后偏移1000,同类的Window逐个递增5,这些值在WindowManagerService中定义,代码如下所示。

    /** How much to multiply the policy's type layer, to reserve room     * for multiple windows of the same type and Z-ordering adjustment     * with TYPE_LAYER_OFFSET. */    static final int TYPE_LAYER_MULTIPLIER = 10000;    /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above     * or below others in the same layer. */    static final int TYPE_LAYER_OFFSET = 1000;    /** How much to increment the layer for each window, to reserve room     * for effect surfaces between them.     */    static final int WINDOW_LAYER_MULTIPLIER = 5;

Java层与Native层的Layer设置是通过SurfaceControl的setLayer完成的,在Native层由SurfaceComposer进行合成。

5、WindowState

WindowState是Android中的事实Window,WindowManager真正管理的是WindowState而不是Window。WindowState在WindowManagerService中创建,从上面的addView的时序图中可以看出。创建WindowState之后,还需要设置上文提到的Window Layer,通过InputChannel与IMS取得联系,将Session中维护的Window个数加1,最后通过WindowToken将这个WindowState添加到WindowContainer中。

6、WindowToken

WindowToken是个容器,将相关的WindowState收集到一起,同样是在WindowManagerService中创建。真正的token是IBinder类型的成员变量token,用于IPC。WindowToken有个子类AppWindowToken,用于Application和Activity。

7、Session

Session是个客户端对象,每个进程只有一个,与WindowManagerService进行交互。Session对应的interface为IWindowSession,在WindowManagerGlobal中实例化。

8、Surface

View或Window真正地是在一个Surface上进行描画的,Surface即一个Buffer,由辅助类SurfaceControl进行控制,上文提到的Window Layer的设置就是由SurfaceControl与Native层进行交互的。

更多相关文章

  1. .Net 转战 Android(安卓)4.4 日常笔记(10)--PullToRefresh下拉刷新
  2. 【android】与pc机进行UDP通信
  3. Android使用ADB启动应用程序
  4. Android(安卓)SDK下载和更新失败的解决方法!!!
  5. Android: 自定义Tab样式
  6. android 显示特殊符号
  7. Android(安卓)Custom Dialog错误Unable to add window -- token
  8. Android正确关闭线程
  9. ubuntu 下 配置 Android(安卓)NDK开发环境

随机推荐

  1. android ui显示技巧和注意事项
  2. 关于android的各种disk images(看过的讲a
  3. Eclipse中使用Ant打Android包报错解决方
  4. android平台的几个编译命令----make,mmm,
  5. Android:背景渐变色
  6. 【Android(BLE)】Android(BLE)之蓝牙权限
  7. 关于Android(安卓)Studio打包混淆以及上
  8. [学习笔记] Android群英传:Android系统信
  9. android第二行代码总结:二、UI
  10. 【Android】精通Android UI设计