安卓高手之路之 WindowManager
安卓中的画面不是纯粹由window组成。而是改成了window+view的组织模式。window是一个顶层窗口的概念。view就相当于在window内的控件。而subwindow则是依附于window的一些对话框。安卓在对window进行管理的时候,将window分为很多层,不同的层又对应于不同的window类型。下面这个图阐释了这种概念:

安卓首先将窗口按照layer分层,然后每一层又有很多window,每一个window又包含了很多的view和sublayer。这些分层的概念对于用户端是透明的,用户端只知道windowType,这样,用户就能通过
windowType的命名从直观概念上知道窗口大概表现出来是什么样子的。下面是windowTYpe转换为
layer的函数:
- public int windowTypeToLayerLw(int type) {
- if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
- return APPLICATION_LAYER;
- }
- switch (type) {
- case TYPE_STATUS_BAR:
- return STATUS_BAR_LAYER;//14
- case TYPE_STATUS_BAR_PANEL:
- return STATUS_BAR_PANEL_LAYER;//15
- case TYPE_STATUS_BAR_SUB_PANEL:
- return STATUS_BAR_SUB_PANEL_LAYER;//13
- case TYPE_SYSTEM_DIALOG:
- return SYSTEM_DIALOG_LAYER;//5
- case TYPE_SEARCH_BAR:
- return SEARCH_BAR_LAYER;//4 //4
- case TYPE_PHONE:
- return PHONE_LAYER;//3 //3
- case TYPE_KEYGUARD:
- return KEYGUARD_LAYER;//11
- case TYPE_KEYGUARD_DIALOG:
- return KEYGUARD_DIALOG_LAYER;//12
- case TYPE_SYSTEM_ALERT:
- return SYSTEM_ALERT_LAYER;//8
- case TYPE_SYSTEM_ERROR:
- return SYSTEM_ERROR_LAYER;//19
- case TYPE_INPUT_METHOD:
- return INPUT_METHOD_LAYER;//9
- case TYPE_INPUT_METHOD_DIALOG:
- return INPUT_METHOD_DIALOG_LAYER;//10
- case TYPE_VOLUME_OVERLAY:
- return VOLUME_OVERLAY_LAYER;//16
- case TYPE_SYSTEM_OVERLAY:
- return SYSTEM_OVERLAY_LAYER;//17
- case TYPE_SECURE_SYSTEM_OVERLAY:
- return SECURE_SYSTEM_OVERLAY_LAYER;//21
- case TYPE_PRIORITY_PHONE:
- return PRIORITY_PHONE_LAYER;//7
- case TYPE_TOAST:
- return TOAST_LAYER;//6
- case TYPE_WALLPAPER:
- return WALLPAPER_LAYER;// 2
- case TYPE_DRAG:
- return DRAG_LAYER;//20
- case TYPE_POINTER:
- return POINTER_LAYER; //23
- case TYPE_NAVIGATION_BAR:
- return NAVIGATION_BAR_LAYER;//18
- case TYPE_BOOT_PROGRESS:
- return BOOT_PROGRESS_LAYER; //22
- case TYPE_HIDDEN_NAV_CONSUMER:
- return HIDDEN_NAV_CONSUMER_LAYER; //24
- }
- Log.e(TAG, "Unknown window type: " + type);
- return APPLICATION_LAYER;
- }
很多人看到这个后不知道怎么分析,一下子被从2到24层的结构吓坏了。那么我就分析一下,这些层次关系。我们只要找到一个突破点,那就是锁屏所在的层,而在锁屏之上的层暂时不要关心:
case TYPE_KEYGUARD:
return KEYGUARD_LAYER;//11
锁屏之下的层依次为:
//输入法对话框
case TYPE_INPUT_METHOD_DIALOG:
return INPUT_METHOD_DIALOG_LAYER;//10
//输入法
case TYPE_INPUT_METHOD:
return INPUT_METHOD_LAYER;//9
//系统警告[低电等]
case TYPE_SYSTEM_ALERT:
return SYSTEM_ALERT_LAYER;//8
// case TYPE_PRIORITY_PHONE:
return PRIORITY_PHONE_LAYER;//7
case TYPE_TOAST:
return TOAST_LAYER;//6
case TYPE_SYSTEM_DIALOG:
return SYSTEM_DIALOG_LAYER;//5
case TYPE_SEARCH_BAR:
return SEARCH_BAR_LAYER;//4 //4
case TYPE_PHONE:
return PHONE_LAYER;//3 //3
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
return APPLICATION_LAYER;
}
case TYPE_WALLPAPER:
return WALLPAPER_LAYER;// 2
从上可以看出,大部分是可以理解的。只有如下两种不好理解:
TYPE_PHONE 3 和 TYPE_PRIORITY_PHONE 7, 很明显与电话有关。
TYPE_PHONE 3 这个基本上没有使用只有在CompatModeDialog用了一下,而TYPE_PRIORITY_PHONE 则是锁网用的。这样可以给运营商带来更多福利。
2.KEYGUARD_LAYER之上又是什么呢?依次如下:
case TYPE_KEYGUARD_DIALOG:
return KEYGUARD_DIALOG_LAYER;//12 关机时候使用
case TYPE_STATUS_BAR_SUB_PANEL:
return STATUS_BAR_SUB_PANEL_LAYER;//13
case TYPE_STATUS_BAR:
return STATUS_BAR_LAYER;//14
case TYPE_STATUS_BAR_PANEL:
return STATUS_BAR_PANEL_LAYER;//15
case TYPE_VOLUME_OVERLAY:
return VOLUME_OVERLAY_LAYER;//16
case TYPE_SYSTEM_OVERLAY:
return SYSTEM_OVERLAY_LAYER;//17
这些为一类,都好理解。从 SYSTEM_OVERLAY_LAYER往下,基本上就是不常见的了
case TYPE_NAVIGATION_BAR:
return NAVIGATION_BAR_LAYER;//18
case TYPE_SYSTEM_ERROR:
return SYSTEM_ERROR_LAYER;//19
case TYPE_DRAG:
return DRAG_LAYER;//20
case TYPE_SECURE_SYSTEM_OVERLAY:
return SECURE_SYSTEM_OVERLAY_LAYER;//21
case TYPE_BOOT_PROGRESS:
return BOOT_PROGRESS_LAYER; //22
case TYPE_POINTER:
return POINTER_LAYER; //23
case TYPE_HIDDEN_NAV_CONSUMER:
return HIDDEN_NAV_CONSUMER_LAYER; //24
可以看出大部分的对话框无法加在锁屏之上。那么有些对话框希望在锁屏的时候能显示,同时,在不锁屏的时候又能保持按照一般对话框来处理。该如何办呢?例如电话,闹钟等。第一种方法,动态改变window的type。根据当前是否正在锁屏,来设置不同的layer来处理。第二种,在锁屏的时候,如果启动了这种window,就隐藏掉锁屏。等这种window被remove走之后,再显示锁屏。
安卓高手之路之 WindowManager的更多相关文章
- 安卓高手之路之 ClassLoader
我不喜欢那些泛泛而谈的去讲那些形而上学的道理,更不喜欢记那些既定的东西.靠记忆去弥补思考的人,容易陷入人云亦云的境地,最后必定被记忆所围困,而最终消亡的是创造力.希望这个高手之路系列能够记录我学习安卓 ...
- ClassLoader使用记录《安卓高手之路》
我不喜欢那些泛泛而谈的去讲那些形而上学的道理,更不喜欢记那些既定的东西.靠记忆去弥补思考的人,容易陷入人云亦云的境地,最后必定被记忆所围困,而最终消亡的是创造力.希望这个高手之路系列能够记录我学习安卓 ...
- 安卓高手之路之ClassLoader(二)
因为ClassLoader一定与虚拟机的启动有关系,那么必须从Zygote的启动开始看代码.下面就分析一下这些代码,行数不多: int main(int argc, const char* const ...
- 安卓高手之路之PackageManagerservice
源码位置:frameworks/base/core/java/android/content/pm/PackageParser.java 源文件路径:android\frameworks\base\s ...
- 安卓高手之路之java层Binder
很多人一提到Binder就说代理模式,人云亦云的多,能理解精髓的少. 本篇文章就从设计角度分析一下java层BInder的设计目标,以及设计思路,设计缺陷,从而驾驭它. 对于[邦德儿]的理解, 从通信 ...
- 安卓高手之路之ClassLoader(三)
由于看C++和C代码看得很累,很辛苦.上一章终于解脱到java代码中来了. 第一个getClassLoader发生在main的preload方法中, public static void main(S ...
- 王家林的“云计算分布式大数据Hadoop实战高手之路---从零开始”的第十一讲Hadoop图文训练课程:MapReduce的原理机制和流程图剖析
这一讲我们主要剖析MapReduce的原理机制和流程. “云计算分布式大数据Hadoop实战高手之路”之完整发布目录 云计算分布式大数据实战技术Hadoop交流群:312494188,每天都会在群中发 ...
- 云计算分布式大数据Hadoop实战高手之路第七讲Hadoop图文训练课程:通过HDFS的心跳来测试replication具体的工作机制和流程
这一讲主要深入使用HDFS命令行工具操作Hadoop分布式集群,主要是通过实验的配置hdfs-site.xml文件的心跳来测试replication具体的工作和流程. 通过HDFS的心跳来测试repl ...
- 云计算分布式大数据Hadoop实战高手之路第八讲Hadoop图文训练课程:Hadoop文件系统的操作实战
本讲通过实验的方式讲解Hadoop文件系统的操作. “云计算分布式大数据Hadoop实战高手之路”之完整发布目录 云计算分布式大数据实战技术Hadoop交流群:312494188,每天都会在群中发布云 ...
随机推荐
- IoC(控制反转)
在传统的编程中,我们通过内部代码来控制组件之间的关系,但是这种实现方式,容易造成组件之间的高耦合.IoC能够很好地解决这个问题,它将组件间的关系从程序内部上提到外部容器来管理.IoC的核心目标是通过简 ...
- 使用ncc分析代码
1 ncc是一个编译器, 用于输出程序的一些调用信息等, 可以查看函数调用关系, 支持函数指针, 查看数据结构和代码. 可以用来分析和理解代码. “" ... with ncc, in le ...
- 转-问自己:UI设计注意的十个问题
UI 设计需要自问的 10个问题 UI 设计的魅力在于,你不仅需要适当的技巧,更要理解用户与程序的关系.一个有效的用户界面关注的是用户目标的实现,包括视觉元素与功能操作在内的所有东西都需要完整一致 ...
- 千万别把js的正则表达式方法和字符串方法搞混淆了
我们在字符串操作过程中肯定经常用了test() split() replace() match() indexof()等方法,很多人经常把用法写错了,包括我,所以今天细细的整理了下. test()是判 ...
- int型长度
Ø 基本数据类型 C语言中只有4中基本数据类型——整型.浮点型.指针和聚合类型(如数组和结构等):所有其他类型都是从这4种基本类型的某种变化或组合派生而来. 一.整型家族 整型家族包括char.sh ...
- c++中的 extern "C"(转载)
比如说你用C 开发了一个DLL 库,为了能够让C ++语言也能够调用你的DLL 输出(Export) 的函数,你需要用extern "C" 来强制编译器不要修改你的函数名. 通常, ...
- Windows Azure 配置多个站点的虚拟网络连接
通过上一篇"Windows Azure 虚拟网络配置(Site to Site)" 我们建立了可以进行Site to Site连接的虚拟网络,配置过后有些朋友会有疑问:如果需要连接 ...
- 《学习OpenCV》练习题第四章第三题a
#include <highgui.h> #include <cv.h> #include "opencv_libs.h" #pragma comment ...
- cc.RepeatForever和cc.Spawn冲突
正确 var tmpShip3 = cc.Sprite.createWithSpriteFrameName("w1_1.png"); tmpShip3.setPosition(,) ...
- 监听mysql是否挂了
监听mysql是否挂了,如果挂了就重启mysql 方式一: #!/bin/bash pgrep -x mysqld &> /dev/null if [ $? -ne 0 ] then e ...