Android R WMS窗口相关流程

252 阅读3分钟

什么是Window

窗口即是屏幕上的一块用于绘制各种UI元素并可以响应用户输入的一个矩形区域。从原理上讲,窗口的概念是独自占有一个Surface实例的显示区域(我们在屏幕上看到的图形都需要绘制在Surface上);

Window是个抽象类其实现类为PhoneWindow。

LayoutParams.type

valuetypedecs
0 - 999应用程序窗口一般情况下应用显示的窗口就是此类型
1000 - 1999子窗口,也可以叫普通弹窗Dialog 或 PopWindow 等显示的类型,type 值较高,会显示在应用程序窗口之上普通弹窗显示需要一个依附的 window ,弹窗的显示需要 token 非空,token 来自依附的 window
2000 - 2999系统级窗口最高等级的窗口,一般作为系统自身应用使用,例如来电、下拉屏的显示等要求应用程序安装于 /system/app,签名需要使用系统签名,2038 特殊值除外 特殊值 2038,即 TYPE_APPLICATION_OVERLAY,该值是唯一不用作为系统应用就可以使用的系统级窗口。如果有需要遮住 0 - 1999 的,使用即可

App resume流程

WMS窗口创建架构.png

当Activity.onResume()被调用之后,客户端会与WMS进行通信将我们的布局显示在屏幕上;

在这个过程中,涉及到一个概念:mDrawState

namevaluedesc
NO_SURFACE0mDrawState在定义的时候,默认 = 0,即NO_SURFACE 当一个窗口刚刚被WMS执行addWindow()方法创建的时候,WindowStateAnimator在WindowState的构造函数中一起被创建,在relayoutWindow之前,窗口是没有Surface的,所以不可能被显示出来,此时状态就是NO_SURFACE;
DRAW_PENDING1客户端调用了relayoutWindow(),这个时候通过WindowManagerServcice的createSurfaceControl()创建了SurfaceControl,然后为窗口创建了一块空白的Surface,此时需要客户端在Surface上作画,但由于Surface为空白状态,所以还是不能显示出;
COMMIT_DRAW_PENDING2在获取到要绘制的Surface时,ViewRootImpl就通过Canvas在Surface上进行绘制,绘制完成之后会调用Session的finishDrawing()方法,调用到WMS的finishDrawingWindow()方法;
READY_TO_SHOW3在WMS内部的findDrawingWindow()在设置完状态后,接着执行了mWindowPlacerLocked.requestTraversal()来请求刷新窗口,跟着调用关系,最终会调用到DIsplayContent的applySurfaceChangesTransaction()方法
HAS_DRAWN4最后阶段会执行WindowState的performShowLocked()显示画面

在WMS中,我们可以通过一个状态值mDrawState来划分几个阶段:

NO_SURFACE

  • 客户端通知WMS创建一个窗口,并添加到WindowToken,即addToDisplayAsUser阶段;
  • 客户端通知WMS创建Surface,并计算窗口尺寸大小,即relayoutWindow阶段;

DRAW_PENDING

  • 客户端获取到WMS计算的窗口大小后,进一步测量该窗口下View的宽度和高度,即performMeasure阶段;
  • 客户端确定该窗口下View的尺寸和位置,即performLayout阶段;
  • 确定好View的尺寸大小位置之后,便对View进行绘制,即performDraw阶段;

COMMIT_DRAW_PENDING

  • 通知WMS,客户端已经完成绘制,即reportDrawFinished阶段;

READY_TO_SHOW

  • WMS接收到客户端通知后,紧接着向WMS Animator发送通知,即commitFinishDrawingLocked阶段;

HAS_DRAWN

  • WMS进行系统窗口的状态刷新以及动画处理,并最终将Surface显示出来,即performShowLocked阶段;

Resume 细节

handleResumeActivity

app_start.png

add View

wm_addView.png

add Window

addToDisplayAsUser.png

relayout

relayout.png

relayout完成之后,WMS端就为Client创建好了对应的SurfaceControl实例,Client端需要中SurfaceControl中获取对应的Surface作为Canvas进行绘制;

Surface_copyFrom.png

finish Draw

finish_Draw.png

commit Finish Draw & perform Show

applySurfaceChangesTransaction.png