1.窗口的类型与层级
窗口的类型分为三类ApplicationWindow(1-99) SubWindow(1000-1999) SystemWindow(2000-2999)
1.1 Application Window
/**
* 应用程序窗口类型的起始值
*/
public static final int FIRST_APPLICATION_WINDOW = 1;
/**
* 应用程序窗口类型的基础值,其他窗口类型以此为基础
*/
public static final int TYPE_BASE_APPLICATION = 1;
/**
* 普通应用程序的窗口类型
*/
public static final int TYPE_APPLICATION = 2;
/**
*应用程序的启动窗口类型,它不能由应用程序本身使用,而是android系统为应用程序启动前设计的窗口--当真正的应用窗口启动后就消失了
*/
public static final int TYPE_APPLICATION_STARTING = 3;
/**应用程序窗口类型的最大值
* End of types of application windows.
*/
public static final int LAST_APPLICATION_WINDOW = 99;
1.2 Sub Window
/**
*子窗口类型的起始值
*/
public static final int FIRST_SUB_WINDOW = 1000;
/**
* 应用程序的panel子窗口,在它的父窗口之上显示
*/
public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;
/**
* 用于显示多媒体内容的子窗口,位于父窗口之下
*/
public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1;
/**
* 也是一种panel子窗口,位于父窗口以及所有TYPE_APPLICATION_PANEL子窗口之上
*/
public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2;
/**
Dialog窗口,如menu类型
*/
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3;
/**
* 多媒体窗口的覆盖层,位于TYPE_APPLICATION_MEDIA和应用程序窗口之间,通常需要时透明的才有意义。(目前处于未开放状态)
*/
public static final int TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW+4;
/**
* 子窗口类型的结束值
*/
public static final int LAST_SUB_WINDOW = 1999;
1.3System Window
/**
* 系统窗口的起始值
*/
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;
/**
* Alert窗口,通常位于其他应用程序之上
*/
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;
/**
* 系统覆盖层窗口,这种类型的窗口不能接受input焦点,否则会与屏保发生冲突
*/
public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6;
/**
*电话优先窗口,如屏保状态下显示来电窗口.
*/
public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7;
/**
* Window type: panel that slides out from the status bar
*
*/
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_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_HIDDEN_NAV_CONSUMER = FIRST_SYSTEM_WINDOW+22;
/**
* 用于模拟第二个显示设备
*/
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: Recents. Same layer as {@link #TYPE_SYSTEM_DIALOG} but only appears on
* one user's screen.
* In multiuser systems shows on all users' windows.
* @hide
*/
public static final int TYPE_RECENTS_OVERLAY = FIRST_SYSTEM_WINDOW+28;
/**
* 系统窗口结束
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
当某个进程向WMS申请窗口时,需要指定窗口的类型(注意:除个别特殊情况外应用程序是不能创建系统窗口的,因为系统会做权限检查)。然后WMS会根据用于申请的窗口类型以及当前系统中已有的窗口情况来给它分配一个最终的层级值。数值越大的窗口,在WMS中的优先级越高,最终在屏幕上显示时就越靠近用户。
系统运行期间,很可能有多个窗口属于同一种窗口类型(例如多个应用程序在运行就会有多个ApplicationWindow)。
1.4窗口层级值的计算
private final void assignLayersLocked(WindowList windows) {
int N = windows.size();//
int curBaseLayer = 0;//类型值
int curLayer = 0;//层值
int i;
boolean anyLayerChanged = false;
for (i=0; i<N; i++) {
final WindowState w = windows.get(i);
final WindowStateAnimator winAnimator = w.mWinAnimator;
boolean layerChanged = false;
int oldLayer = w.mLayer;
if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
|| (i > 0 && w.mIsWallpaper)) {
//如果这个窗口的基础层级和前一个处理的窗口层级一样
//同一基础层级的窗口,只要加上间隔就可以了
curLayer += WINDOW_LAYER_MULTIPLIER;
w.mLayer = curLayer;
} else {
//窗口的基础层级变了,curBaseLayer换成当前这个窗口的
curBaseLayer = curLayer = w.mBaseLayer;
w.mLayer = curLayer;
}
if (w.mLayer != oldLayer) {
layerChanged = true;
anyLayerChanged = true;
}
//......
}
}
mBaseLayer是WindowState的成员变量,在WindowState的构造函数中被赋值###
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, final DisplayContent displayContent) {
if ((mAttrs.type >= FIRST_SUB_WINDOW &&
mAttrs.type <= LAST_SUB_WINDOW)) {
//windowTypeToLayerLw函数针对不同的窗口类型做了映射,具体的映射规则取决于WindowManagerPolicy
mBaseLayer = mPolicy.windowTypeToLayerLw(
attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ WindowManagerService.TYPE_LAYER_OFFSET;
//计算子窗口
mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
} else {
// The multiplier here is to reserve space for multiple
// windows in the same type layer.
mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
* WindowManagerService.TYPE_LAYER_MULTIPLIER
+ WindowManagerService.TYPE_LAYER_OFFSET;
mSubLayer = 0;
}
}
网友评论