SurfaceFlinger 前面说的,就是一个surface的合成。SurfaceFlinger就是一个默默的记录着,它不会对surface的内容有什么改动。

WMS(WindowsManagerService)就是对surface的管理,或者说是一个大管家。它负责协调各方面资源。

ViewRoot就是一个个演员,负责表演(产生surface)。

从IO系统角度而言,WMS至少要干这几件事。

全局窗口管理

全局事件派发

键盘

触摸屏

1.WMS综述

1)WMS将以同AMS等一样的形式,系统server的一部分。

由SystemServer负责启动

知道系统关闭才能停止

发生异常的时候,能够自我恢复

2)SurfaceFlinger 和WMS将有很多交集。

3)有显示需求的图层。可以想见,界面显示是分不同层级的。

4)inputManagerService 当有按键或者触摸事件时,WMS时最好的管理员。

5)AMS 同WMS 也有交互。

6)Bind交互

从WMS窗口的实现来讲,主要包含如下子功能

窗口的添加和删除

启动窗口

窗口动画

窗口大小

窗口层级

事件派发

1.1WMS的启动

services\java\com\android\server\SystemServer.java

private void startOtherServices() {
inputManager = new InputManagerService(context);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); traceBeginAndSlog("StartWindowManagerService");
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
}

1.2 WMS提供的服务

public class IWindowManagerImpl implements IWindowManager 

提供了很多功能,包含屏幕获取,获取窗口大小,启动窗口等

1.3 WMS工作方式

WMS很复杂,以工作方式作为切入点是比较合适的。

WMS,AMS,Activity之间的关系

WMS 可以和AMS相互调用,Activity有Window的对象。

   public ViewRootImpl(Context context, Display display) {
mContext = context;
mWindowSession = WindowManagerGlobal.getWindowSession();
public static IWindowSession getWindowSession() {
synchronized (WindowManagerGlobal.class) {
if (sWindowSession == null) {
try {
InputMethodManager imm = InputMethodManager.getInstance();
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
},
imm.getClient(), imm.getInputContext());
} catch (RemoteException e) {
Log.e(TAG, "Failed to open window session", e);
}
}
return sWindowSession;
}
}

可以看到,是windowmanager提供的一个session

当启动一个activity的时候,AMS会把记录放到activityRecord。同时WMS会对activity进行记录,就用WindowState

2.窗口属性

2.1窗口的层级和类型

窗口的类型很多,不过,可以统一划分为3类,Application Window,System Window,Sub Window.

它们全部定义在WindowManager.java

2.1.1 普通窗口

2.1.2 Sub Window

这一类主要就是Dialog 之类的。

2.1.3 系统窗口

系统窗口非常多,主要由系统状态栏,来电,输入法等。

具体的取值:

Application Window:1-99

SubWindow:100-1999

SystemWindow:2000-2999

当某个进程向WMS申请一个Window的时候,需要告诉系统窗口的类型。如果有3个app在运行中,则前台有3个窗口,这个时候,需要能调整它们的优先级。

对于Window的显示,层级越高,显示越前面。这个显示的动作,由SurfaceFlinger来处理。

 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
mAttrs.type <= LAST_SUB_WINDOW)) {
// The multiplier here is to reserve space for multiple
// windows in the same type layer.
mBaseLayer = mPolicy.windowTypeToLayerLw(
attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ WindowManagerService.TYPE_LAYER_OFFSET;
mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
mAttachedWindow = attachedWindow;
......

所有窗口的mBaseLayer可以分几步获得:

@Step1:windowTypeToLayerLw

这个根据不同的窗口类型做了简单的映射。

@Override
public int windowTypeToLayerLw(int type) {
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
return 2;
}
switch (type) {
case TYPE_PRIVATE_PRESENTATION:
return 2;
case TYPE_WALLPAPER:
// wallpaper is at the bottom, though the window manager may move it.
return 2;
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_DREAM:
// used for Dreams (screensavers with TYPE_DREAM windows)
return 10;
case TYPE_SYSTEM_ALERT:
// like the ANR / app crashed dialogs
return 11;
case TYPE_INPUT_METHOD:
// on-screen keyboards and other such input method user interfaces go here.
return 12;
case TYPE_INPUT_METHOD_DIALOG:
// on-screen keyboards and other such input method user interfaces go here.
return 13;
case TYPE_KEYGUARD_SCRIM:
// the safety window that shows behind keyguard while keyguard is starting
return 14;
case TYPE_STATUS_BAR_SUB_PANEL:
return 15;
case TYPE_STATUS_BAR:
return 16;
case TYPE_STATUS_BAR_PANEL:
return 17;
case TYPE_KEYGUARD_DIALOG:
return 18;
case TYPE_VOLUME_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
return 19;
case TYPE_SYSTEM_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
return 20;
case TYPE_NAVIGATION_BAR:
// the navigation bar, if available, shows atop most things
return 21;
case TYPE_NAVIGATION_BAR_PANEL:
// some panels (e.g. search) need to show on top of the navigation bar
return 22;
case TYPE_SYSTEM_ERROR:
// system-level error dialogs
return 23;
case TYPE_MAGNIFICATION_OVERLAY:
// used to highlight the magnified portion of a display
return 24;
case TYPE_DISPLAY_OVERLAY:
// used to simulate secondary display devices
return 25;
case TYPE_DRAG:
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
return 26;
case TYPE_ACCESSIBILITY_OVERLAY:
// overlay put by accessibility services to intercept user interaction
return 27;
case TYPE_SECURE_SYSTEM_OVERLAY:
return 28;
case TYPE_BOOT_PROGRESS:
return 29;
case TYPE_POINTER:
// the (mouse) pointer layer
return 30;
}
Log.e(TAG, "Unknown window type: " + type);
return 2;
}

windowTypeToLayerLw

对于sub window而言,窗口类型取决于父窗口类型。

@Step2. 上一步获得的值*TYPE_LAYER_MULTIPLIER(10000)+TYPE_LAYER_OFFSET(1000)

同一类型的窗口可能由很多。1000.是为了移动一组window而设计的。

@Step3.subWindowTypeToLayerLw 计算子窗口的layer。偏移量在1,或者-2都有可能。所以子窗口现在在父窗口的上面。或者下面,都可能。

2.2窗口属性

windowmanagerprolicy。android显示的同一的规则。手机有StatusBar,而平板有CombinedBar。类似,但是功能不一样。

/**
* WindowManagerPolicy implementation for the Android phone UI. This
* introduces a new method suffix, Lp, for an internal lock of the
* PhoneWindowManager. This is used to protect some internal state, and
* can be acquired with either the Lw and Li lock held, so has the restrictions
* of both of those when held.
*/
public class PhoneWindowManager implements WindowManagerPolicy

PhoneWindowManager 和call没有关系,它表述andorid phone的UI显示规则。

2.3 layoutParams

1)Type

窗口类型,不再说明。

2)Flags

最典型的就是,保持屏幕常亮。这个可以使用FLAG_KEEP_SCREEN_ON。

在activity下使用这个方法就可以:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

FLAG_ALLOW_LOCK_WHILE_SCREEN_ON:只要此窗口可见,即使屏幕点亮,也允许锁屏。 从现实来讲,有这个需求吗? 测验后,实际效果,会半暗屏,但不会上锁。

FLAG_DIM_BEHIND:在窗口后面的东西,都将变暗。 dialog之类的比较常用。一个非常有用的flag,尤其是需要做蒙层的时候。

public class DimDialog extends Dialog {
private static final float DIMDIALOG_TRANTANT = 0.3f;
private static final float DIMDIALOG_BG_TRANTANT = 0.8f;
public DimDialog(Context context) {
super(context);
setAttributes();
} private void setAttributes() {
WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha=DIMDIALOG_TRANTANT;
lp.dimAmount = DIMDIALOG_BG_TRANTANT;
getWindow().setAttributes(lp);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
} public DimDialog(Context context, int themeResId) {
super(context, themeResId);
setAttributes();
} protected DimDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
setAttributes();
}
}

DimDialog

FLAG_BLUR_BEHIND:高斯模糊,目前已经废弃,对性能的影响巨大,不建议使用。

FLAG_NOT_FOCUSABLE:窗口不处理事件,将会传递到后面的其他窗口。同时FLAG_NOT_TOUCH_MODAL也会被设置。

FLAG_NOT_TOUCHABLE:touch 事件传递到后面的窗口使用。

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

FLAG_KEEP_SCREEN_ON:最常用,最经典的模式,屏幕常量

FLAG_FULLSCREEN:全屏,没有状态栏。

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

动态调整全屏状态:

    private void full(boolean enable) {
if (enable) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(lp);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} else {
WindowManager.LayoutParams attr = getWindow().getAttributes();
attr.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attr);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
}

full

FLAG_FORCE_NOT_FULLSCREEN:同FLAG_FULLSCREEN相反

FLAG_SECURE:窗口无法被截屏。不安全的应用也无法显示等。

FLAG_SCALED:按用户的要求调整窗口

FLAG_IGNORE_CHEEK_PRESSES: 当屏幕有可能贴着脸时,这一选项可防止面颊对屏幕造成误操作。

FLAG_LAYOUT_INSET_DECOR:只能和FLAG_LAYOUT_IN_SCREEN一起使用,充分考虑各种情况

FLAG_SHOW_WHEN_LOCKED:在锁屏的时候,可以显示该页面,也是非常重要的flag。关于锁屏的问题可以参考 锁屏上显示Activity 这篇博客,此处不再叙述。

FLAG_SHOW_WALLPAPER:当前activity为透明或者半透明的时候,让壁纸作为背景。

        WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha = 0.5f;
getWindow().setAttributes(lp);//设置透明度
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);//设置壁纸

FLAG_TURN_SCREEN_ON:把屏幕点亮

FLAG_DISMISS_KEYGUARD:解锁。是指普通锁屏,但是安全锁(图案或者密码锁屏界面)是无效的。 在电话界面,可以直接解锁,而不需进入锁屏界面。

FLAG_HARDWARE_ACCELERATED:硬件加速,具体取决于硬件条件。

3)systemUiVisibilty

这个flag,定义在View中,

这里先明确,这些flag起作用,首先这个view必须是可见的。而window的flag是全局的。

View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏 View.INVISIBLE 对应属性,隐藏状态栏。

View.SYSTEM_UI_FLAG_FULLSCREEN 和上节讲到的FLAG_FULLSCREEN具有相同的效果,具体的细微差距,请参考http://www.360doc.com/content/15/0204/18/20385871_446270224.shtml 这篇文章。此处不做详细讨论。

根据经验,View可以是临时的,而FLAG_FULLSCREEN 可以是长期的。

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 可以是navigationbar隐藏。

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN activity全屏显示,但是statusbar不会隐藏,会把activity上面的部分,覆盖。

View.SYSTEM_UI_FLAG_IMMERSIVE ,在5.1上测试的结果同SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 类似,activity全屏,但statusbar仍然存在。半透明的状态,但是状态栏点击会有反映。

View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 在statusbar隐藏后,过几秒会自动出现。

这里还要注意getWindow().getDecorView().setSystemUiVisibility();同setContentView(layout.activity_wall_layout);的顺序问题。

android Gui系统之WMS(1)----window flags & view flags的更多相关文章

  1. android Gui系统之WMS(2)----窗口的添加

    Android系统很多,但是最常用的就两类,一类是有系统进场管理的,系统窗口.还有一类就是由应用程序产生的,应用窗口. 1.系统窗口的添加流程 1.1 addStatusBarWindow Phone ...

  2. 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)

    Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...

  3. 图解Android - Android GUI 系统 (5) - Android的Event Input System

    Android的用户输入处理 Android的用户输入系统获取用户按键(或模拟按键)输入,分发给特定的模块(Framework或应用程序)进行处理,它涉及到以下一些模块: Input Reader: ...

  4. 图解Android - System Service 概论 和 Android GUI 系统

    通过 图解Android - Binder 和 Service 一文中,我们已经分析了Binder 和 Service的工作原理.接下来,我们来简要分析Android 系统里面都有哪些重要的Servi ...

  5. 图解Android - Android GUI 系统 (1) - 概论

    Android的GUI系统是Android最重要也最复杂的系统之一.它包括以下部分: 窗口和图形系统 - Window and View Manager System. 显示合成系统 - Surfac ...

  6. Android GUI系统

    图解Android - Android GUI 系统 (1) - 概论 图解Android - Android GUI 系统 (2) - 窗口管理系统 图解Android - Android GUI ...

  7. android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论

    GUI 是任何系统都很重要的一块. android GUI大体分为4大块. 1)SurfaceFlinger 2)WMS 3)View机制 4)InputMethod 这块内容非常之多,但是理解后,可 ...

  8. android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论【转】

    转自:https://www.cnblogs.com/deman/p/5584198.html 阅读目录 1.OpenGL & OpenGL ES 2.Android的硬件接口HAL 3.An ...

  9. android Gui系统之SurfaceFlinger(3)---SurfaceFlinger

    7.SurfaceFlinger SurfaceFlinger在前面的篇幅了,多有涉及. SurfaceFlinger是GUI刷新UI的核心,所以任何关于SurfaceFlinger的改进都会对and ...

随机推荐

  1. 一些C#实用的方法汇总

    代码如下: /// <summary> /// 过滤字符串方法,用于将单引号等特殊符号转化成中文符号 /// </summary> /// <param name=&qu ...

  2. ASP.NET Core 开发-中间件(StaticFiles)使用

    ASP.NET Core 开发,中间件(StaticFiles)的使用,我们开发一款简易的静态文件服务器. 告别需要使用文件,又需要安装一个web服务器.现在随时随地打开程序即可使用,跨平台,方便快捷 ...

  3. WCF Throttling 限流的三道闸口

    WCF Throttling 限流的三道闸口 一.WCF Throttling  流量限制简介 我们期望WCF服务端能够处理尽可能多的并发请求,但是资源是有限的,服务不可能同时处理无限多的并发请求,如 ...

  4. 介绍开源的.net通信框架NetworkComms框架 源码分析(十二)PriorityQueue

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  5. redis sentinel 集群配置-主从切换

    1.配置redis master,redis slave(配置具体操作见上文http://www.cnblogs.com/wangchaozhi/p/5140469.html). redis mast ...

  6. Struts 2.0全面分析

    Struts 2.0 struts 1---前端控制+应用控制+命令模式 webwork ---控制器+拦截器+代理 Struts 2.0 继承了WebWork的设计理念,并没有继承struts 1, ...

  7. WITH RECURSIVE and MySQL

    WITH RECURSIVE and MySQL If you have been using certain DBMSs, or reading recent versions of the SQL ...

  8. Hack语言的类型系统

    基础类型 PHP中主要的基础类型可以在Hack中进行显式类型标注.包含: bool int float string array resource <?hh namespace Hack\Use ...

  9. AFNetworking 3.1

    听说之后AFHttpWorking版本可能会影响到苹果的审核,今天下了最新版本的AFHttpWorking,并且做了简单的封装,我这里是通过cocoapods下载了两个工具 1=AFHttpWorki ...

  10. Oracle Database 11g For Windows7 旗舰版的安装

    系统环境:win7 32位系统 安装步骤: 1,Oracle(甲骨文)官网下载适合自己的数据库安装包,下载地址http://www.oracle.com/technetwork/cn/indexes/ ...