8.2.2 Activity的UI绘制
最后更新于:2022-04-02 05:52:06
ViewRoot的setView函数中,会有一个requestLayout。根据前面的分析可知,它会向ViewRoot发送一个DO_TRAVERSAL消息,来看它的handleMessage函数,代码如下所示:
**ViewRoot.java**
~~~
public void handleMessage(Message msg) {
switch (msg.what) {
......
case DO_TRAVERSAL:
......
performTraversals();//调用performTraversals函数
......
break;
......
}
}
~~~
再去看performTraversals函数,这个函数比较复杂,先只看它的关键部分,代码如下所示:
**ViewRoot.java**
~~~
private void performTraversals() {
finalView host = mView;//还记得这mView吗?它就是DecorView喔
booleaninitialized = false;
booleancontentInsetsChanged = false;
booleanvisibleInsetsChanged;
try {
relayoutResult= //①关键函数relayoutWindow
relayoutWindow(params, viewVisibility,insetsPending);
}
......
draw(fullRedrawNeeded);// ②开始绘制
......
}
~~~
1. relayoutWindow的分析
performTraversals函数比较复杂,暂时只关注其中的两个函数relayoutWindow和draw即可。先看第一个relayoutWindow,代码如下所示:
**ViewRoot.java**
~~~
private intrelayoutWindow(WindowManager.LayoutParams params,
int viewVisibility, boolean insetsPending)throws RemoteException {
//原来是调用IWindowSession的relayOut,暂且记住这个调用
int relayoutResult = sWindowSession.relayout(
mWindow, params,
(int) (mView.mMeasuredWidth * appScale + 0.5f),
(int) (mView.mMeasuredHeight * appScale + 0.5f),
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets,
mPendingConfiguration, mSurface); mSurface做为参数传进去了。
}
......
}
~~~
relayoutWindow中会调用IWindowSession的relayout函数,暂且记住这个调用,在精简流程后再进行分析。
2. draw的分析
再来看draw函数。这个函数非常重要,它可是Acitivity漂亮脸蛋的塑造大师啊,代码如下所示:
**ViewRoot.java**
~~~
private void draw(boolean fullRedrawNeeded) {
Surface surface = mSurface;//mSurface是ViewRoot的成员变量
......
Canvascanvas;
try {
int left = dirty.left;
int top = dirty.top;
int right = dirty.right;
int bottom = dirty.bottom;
//从mSurface中lock一块Canvas
canvas = surface.lockCanvas(dirty);
......
mView.draw(canvas);//调用DecorView的draw函数,canvas就是画布的意思啦!
......
//unlock画布,屏幕上马上就会见到漂亮宝贝的长相了。
surface.unlockCanvasAndPost(canvas);
}
......
}
~~~
UI的显示好像很简单嘛!真的是这样的吗?在揭露这个“惊天秘密”之前我们先总结一下Activity的显示流程。
';