经过上面的步骤,应用程序的ViewRootImpl已经被WindowManagerService识别,并且应用程序已经与SurfaceFlinger建立连接。即创建了SurfaceComposerClient和Client对象
文章开始就已经说了Surface是Window(ViewRootImpl)的UI载体,那Surface是在哪里创建的呢?
Surface的创建
其实一个ViewRootImpl就对应一个Surface。
这点可以通过ViewRootImpl的源码看出:
即ViewRootImpl在构造的时候就new 了一个 Surface。但其实这个新new的Surface并没有什么逻辑,它的构造函数是空的。
public final class ViewRootImpl implementsViewParent,
View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {//...
public final Surface mSurface = newSurface();//...
public voidsetView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
...
requestLayout();//susion 请求layout。先添加到待渲染队列中
...
res= mWindowSession.addToDisplay(mWindow, ...); //WindowManagerService会创建mWindow对应的WindowState
...
}
@Overridepublic voidrequestLayout() {if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested= true;
scheduleTraversals();
}
}
}
即在向WindowManagerService请求创建WindowState之前,调用了requestLayout(),这个方法会引起ViewRootImpl所管理的整个view tree的重新渲染。它最终会调用到scheduleTraversals():
voidscheduleTraversals() {
...
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable,null);
...
}
scheduleTraversals()会通过Choreographer来post一个mTraversalRunnable,Choreographer接收显示系统的时间脉冲(垂直同步信号-VSync信号,16ms发出一次),在下一个frame渲染时控制执行这个mTraversalRunnable。
但是mTraversalRunnable的执行至少要在应用程序与SurfaceFlinger建立连接之后。这是因为渲染操作是由SurfaceFlinger负责调度了,如果应用程序还没有与SurfaceFlinger创建连接,那SurfaceFlinger当然不会渲染这个应用程序。所以在执行完mWindowSession.addToDisplay(mWindow, ...)之后,才会执行mTraversalRunnable:
final class TraversalRunnable implementsRunnable {
@Overridepublic voidrun() {
doTraversal();
}
}
doTraversal()会调用到ViewRootImpl.performTraversals(),大部分同学可能知道这个方法是一个view tree的measure/layout/draw的控制方法:
private voidperformTraversals() {
finalView host= mView; //mView是一个Window的根View,对于Activity来说就是DecorView
...
relayoutWindow(params, viewVisibility, insetsPending);
...
performMeasure(chi