助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
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的显示流程。