聊聊 Android 的 GUI 系统( 二 )

  • draw
view渲染内容
  • dispatchDraw
在onDraw之后会调用此方法,分发子元素绘制,主要是针对ViewGroup 。ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而不执行draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用 。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法我是 Window我是在应用框架层,被 JAVA 封装的用来展示窗口的一个抽象类 。我负责可视化内容的排版 。Android 支持的窗口类型很多,不过我们可以统一划分为三大类,即 Application Window、System Window 和 Sub Window 。另外各个种类下还细分为若干子类型,这些都是在我的上司 WindowManager 通过进程通信的方式,去与后台服务 WindowManagerService 通信,最终递交到 SurfaceFlinger 来输出和呈现 。
从用户的角度来说,我就是一个界面;从 SurfaceFlinger 的角度来说,我是一个 Layer ,承载着和界面有关的数据和属性;从 WMS 来说,我是一个 windowstate ,用于管理和界面有关的状态 。
窗口类型与层级Application Window 这类窗口对应应用程序的窗口,取值在 1-99 之间
Type Description FIRST_APPLICATION_WINDOW = 1 应用程序窗口的起始值 TYPE_BASE_APPLICATION = 1 应用程序窗口的基础值 TYPE_APPLICATION = 2 普通应用程序的窗口类型 TYPE_APPLICATION_STARTING = 3 应用程序的启动窗口类型 。它不能由应用程序本身使用,而是Android 系统为应用程序启动前设计的窗口,当真正的窗口启动后它就消失了 TYPE_DRAWN_APPLICATION = 4 用于确保应用程序窗口在显示时已经完成了绘制 LAST_APPLICATION_WINDOW = 99 应用程序窗口的最大值
Sub Window 这类窗口将附着在其他 Window 中,取值在 1000 到 1999 之间
Type Description FIRST_SUB_WINDOW = 1000 子窗口的起始值 TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW 应用程序的 panel 子窗口,在它的父窗口之上显示 TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW + 1 用于显示多媒体内容的子窗口,位于父窗口之下 TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2 也是一种 panel 子窗口,位于父窗口以及所有 TYPE_APPLICATION_PANEL 之上 TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3 Dialog 子窗口,如 menu 类型 TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW + 4 多媒体窗口的覆盖层,位于 TYPE_APPLICATION_MEDIA 和应用程序窗口之间,通常透明才有意义 。此类型属于未开放状态 LAST_SUB_WINDOW = 1999 子窗口的最大值
System Window 对应系统程序采用的窗口类型,取值在 2000 到 2999 之间
Type Description FIRST_SYSTEM_WINDOW = 2000 系统窗口的起始值 TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW 系统状态栏窗口 TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1 系统搜索条窗口 TYPE_PHONE = FIRST_SYSTEM_WINDOW+2 通话窗口 TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3 Alert窗口,如电量不足的提示框 TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4 屏保窗口 TYPE_TOAST = FIRST_SYSTEM_WINDOW+5 短暂的提示框窗口 TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6 系统覆盖窗口,这种类型的窗口不能接收 input 事件 TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7 电话优先窗口 TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8 RecentsAppDialog 就是这种类型的窗口 TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9 屏保时显示的对话框 TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10 系统错误窗口 TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11 输入法窗口 TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12 显示在输入法之上的对话框窗口 TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13 壁纸窗口 TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14 滑动状态栏出现的窗口 YPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19 导航栏窗口 TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20 系统音量条 TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21 开机启动的进度条窗口 TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW+22 导航栏隐藏时用于消耗事件的伪窗口 LAST_SYSTEM_WINDOW = 2999 系统窗口结束
当某个进程向 WMS 申请一个窗口时,它需要指定所需窗口类型,然后 WMS 根据用户申请的窗口类型以及当前系统中已有窗口的情况来给它分配一个最终的层级值,数值越大的窗口,优先级越高,在屏幕上显示时候就越靠近用户 。
窗口属性除了窗口类型外,开发者还可以设置不同的属性来调整窗口的表现,这些属性统一放置在 WindowManager.LayoutParams 中 。其中主要包括以下几个重要的变量: