美文网首页
理解WindowManager和WMS

理解WindowManager和WMS

作者: LeoFranz | 来源:发表于2019-10-15 13:29 被阅读0次

WindowManager

概念扫盲:

  • Window是界面的抽象概念,它是一个抽象类,实现类为PhoneWindow,它包含了view并对view进行管理。
  • WindowManager是管理window的,继承自ViewManager,实现类为WindowManagerImpl,WindowManager会将具体的操作教给WMS处理,他们之间通过Binder通信
  • WMS实现WindowManager的方法,对WindowManager隐藏了部分接口,他们的关系类似于ActivityManager和AMS

继承自ViewManager,后者具备addView,updateViewLayout,removeView三个操作view的方法,WIndowManager加入了Window类型和层级相关的常量。如getDefaultDisplay(),得知WM将当前window添加到哪个屏幕(Display)上了。removeViewImmediate(view)表示在这个方法返回前要执行View.onDetachedFromWindow来完成传入的view相关销毁工作。

Activity绑定window过程
在activity.attach方法中,PhoneWindow生成,其持有activity的引用,同时通过window.setWindowManager方法传入WindowManager,实际上是WindowManagerImpl,同时内部通过createLocalWindowManager将PhoneWindow传入WindowManagerImpl,这样就实现了window和WindowManager的双向引用。

WindowManager通过持有window的引用而操作window,比如添加view,但WindowManager对window的操作是靠其成员变量WindowManagerGlobal实现的。

Window的属性

1、类型和显示次序
WMS是调度者,Window相当于员工,他们之间定义了一些协议(属性),保存在WindowManager.layoutParams中。
窗口分为Application Window、Sub Window、System Window。
子窗口必须依附于其他窗口才能存在,比如popupWindow;系统输入法窗口、Toast、音量窗口就属于系统窗口。

窗口显示次序的基本规则,是根据系统为窗口分配的Z轴次序。这个值是根据窗口的type确定的,type值越大值越靠前,就越靠近用户。当然现实中计算情况比这个复杂。

2、window的标志
就是Flag,包括不接受触摸事件,屏幕常亮、允许窗口在屏幕之外等属性。同样定义在WindowManager.layoutParams中。设置flag有三种方式,addFlag,setFlag和通过给WindowManager.layoutParams设置flag,然后通过addView方法进行添加。
eg:windowManager.addView(mTextView,mWindowLayoutParams);

3、软键盘相关模式
包括调整软件判大小,是否被隐藏之类的属性。可以在清单文件中activity的android:windowSoftInput属性添加或者通过java代码中window.softInputMode属性设置。

Window的操作

基本是addView、updateWindow、removeWindow三大操作。通过WindowManager调度,最终由WMS实现。对于WMS来说,三种类型的窗口添加过程是基本一致的。
一、下面看系统窗口statusBar添加过程:
1、通过StatusBarWindowManager.add方法添加
2、创建LayoutParams配置StatusBar的属性,然后通过windowManger.addView方法将状态栏添加。
2.1 WindowManager的addView方法最终是通过windowManagerImpl实现的,后面转入WindowManagerGlobal。
2.2在WindowmanagerGlobal中,通过window的将需要添加的view添加到mVIews列表,窗口属性添加到mParams列表,创建ViewRootImpl并添加到mRoots列表,最终ViewRootImpl.setView方法将窗口和窗口参数设置到ViewRootImpl中,可见我们添加窗口这一操作通过ViewRootImpl实现的。

ViewRootimpl有很多职责,其中包括

  • View的根并管理View树
  • 触发View的测量、布局和绘制
  • 事件的中转站
  • 管理surface
  • 负责与WMS进行进程间通信

ViewRoot通过调用windowSession.addToDisplay方法——它是IWindowSession的binder客户端对象——实现类在远端Session,运行在WMS所在进程。
每个应用程序对应一个Session。WMS通过ArrayList保存这个Session。剩下的工作中,
远端addToDisplay方法中调用WMS的addWindow方法,WMS为每个添加的窗口分配Surface,并确定窗口显示次序——surface是真正负责显示界面的,WMS将其管理的Surface交由SurfaceFlinger处理,后者将他们混合并绘制。

二、Activity的添加过程
和系统window的添加过程基本类似,在ActivityThread.handleresumeActivity方法中,在其中调用ViewManager的addView方法,不过第一个参数为DecorView,说明activity的窗口中会包含DecorView。

三、Window更新过程
类似于添加流程,在WindowManager中调用updatewindowLayout方法,实际会调用WindowManagerGlobal的updateViewLayout方法,其中删除了原有的params,并重新添加,然后通过ViewRootImpl的setLayoutParams奖更新的参数设置到ViewRootImpl中,其中会经过performtraversals方法,使得Viewtree开始view的绘制流程。其中会通过relayoutWindow调用IWindowSession的relayout方法来更新window视图,除此之外,还会分别调用performMeasure、performLayout、performDraw方法完成完成了view的绘制流程。

WMS

  • 窗口管理,负责窗口的启动,添加和删除。窗口的大小和层级也是WMS确定。窗口管理的核心成员有DisplayContent、WindowToken、WindowState,WMS对接WindowManager
  • 窗口动画,动画管理者为WindowAnimator
  • 输入系统的中转站,通过对窗口的触摸产生的触摸事件,InputManagerService会寻找最合适的窗口处理触摸反馈信息,WMS作为输入系统的中转站。
  • Surface 管理 窗口并不具备绘制的功能。每个窗口都需要一块surface来绘制,为每个窗口分配surface是WMS完成的,它会对接SurfaceFlinger

WMS是在SystemServer进程中创建的,它属于官方系统中其他服务类。其中比较关键的成员变量有mSessions,其中成员类型为Session,每一个需要通过远程通信和WMS进行window操作的客户端都必须通过Session和WMS通信,每个应用程序进程都会对应一个Session。此外还有mWindowMap,继承了HashMap,key类型为IBinder,value类型为WindowState,用来保存窗口信息,在WMS中它用来描述一个窗口。所以mWindowMap就是WMS中保存各种窗口的集合。

WIndow的添加过程(WMS处理部分)

无论是系统窗口还是activity,添加window过程中都会经过WMS的addWindow方法。
addWindow方法主要逻辑如下:对窗口进行权限等相关检查;创建windowToken;将windowToken和WindowState相关联;创建和配置DisplayContent,完成窗口添加到系统前的准备工作。

Window的删除过程

删除从客户端的removeView开始,
检查删除线程,如果不正确就抛出异常;
从ViewRootImpl列表、布局参数和View列表中删除和该window相关的元素;
判断是否可以直接进行删除操作,如果不能就推迟删除操作;
执行远端删除操作,清理和释放与window相关的一切资源,包括Session、对应的surfaceSession资源等。

相关文章

网友评论

      本文标题:理解WindowManager和WMS

      本文链接:https://www.haomeiwen.com/subject/sgirmctx.html