首先亮出几个类:
Activity:基本页面单元
PhoneWindow:每个Activity均会创建一个,内部包含一个DecorView对象,是一个把FrameLayout进行了一定的包装,并提供了一组通用的窗口操作接口。
DecorView:PhoneWindow的子类,包含Activity的所有UI部件,接收用户发起的event事件,如按键等.
ViewRoot:向DecorView分发用户event事件,与WindowManageService交互完成View的绘制.
WindowManageService:对系统中所有窗口进行管理.
上图简单描述了绘制界面时各个成员之间的相互关系。
ActivityManagerService创建Activity线程,激活一个activity
系统调用Instrumentation.newActivity创建一个activity
Activity创建后,attach到一个新创建的phonewindow中。这样Activity获取一个唯一的WindowManager服务的实例
Activity创建过程中使用setcontentView设置用用户UI,这些VIEW被加入到PhoneWindow的ContentParent中。
Activity线程继续执行,当执行到Activity.makeVisible是将根view DecoView加入到WindowManger中,WindowManger实全会为每个DecoView创建对应的ViewRoot
每个ViewRoot拥有一个Surface,每个Surface将会调用底层库创建图形绘制的内存空间。这个底层库就是SurfaceFlinger。SurfaceFlinger同时也负责将个View绘制的图形合到一块(按照Z轴)显示到用户屏幕
上图是从启动Activity到创建View的过程
在上图中,performLaunchActivity函数是关键函数,除了新建被调用的Activity实例外,还负责确保Activity所在的应用程序启动、读取manifest中关于此activity设置的主题信息以及上图中对“6.onCreate”调用也是通过对mInstrumentation.callActivityOnCreate来实现的。图中的“8. mContentParent.addView”其实就是架构图中phoneWindow内DecorView里面的ContentViews,该对象是一个ViewGroup类实例。在调用AddView之后,最终就会触发ViewRoot中的scheduleTraversals这个异步函数,从而进入ViewRoot的performTraversals函数,在performTraversals函数中就启动了View的绘制流程。
下面是performTraversal()函数中最重要的部分代码。
private void performTraversals () {final View host = mView ;...host . measure ( childWidthMeasureSpec , childHeightMeasureSpec );...host . layout ( 0 , 0 , host . getMeasuredWidth (), host . getMeasuredHeight ());...draw ( fullRedrawNeeded );}主要包含三个步骤1.measure 测量过程是先测量父视图,再测量子视图,父视图一定是充满屏幕的,子视图的位置由父视图和子视图本身共同决定 2.layout 确定视图位置,先设置父视图位置,在循环子视图,父视图位置一定程度上决定了子视图位置。 3.draw dispatchDraw()内部for循环调用drawChild()分别绘制每一个子视图,而drawChild()内部又会调用draw()函数完成子视图的内部绘制工作具体内容参照点击打开链接补充下屏幕事件传递:首先WindowManageService接收到事件,然后传递给相应的ViewRoot,再传递给相应的DecoView,DecoView然后传递给他锁包含的View