Android应用程序窗口的UI渲染过程可以分为测量、布局和绘制三个阶段
1、测量(Measure)
...
↓
ViewRootImpl.doTraversal()
↓
ViewRootImpl.performTraversals()
↓
ViewRootImpl.measureHierarchy()
↓
ViewRootImpl.performMeasure()
↓
View.measure()
↓
PhoneWindow$DecorView.onMeasure()
↓
FrameLayout.onMeasure()
↓
ViewGroup.measureChildWithMargins()
2. Android应用程序窗口的布局过程
ViewRootImpl.doTraversal()
↓
ViewRootImpl.performTraversals()
↓
ViewGroup.layout()
↓
View.layout()
↓
FrameLayout.onLayout()
3. Android应用程序窗口的绘制过程
ViewRoot类的成员函数draw首先会创建一块画布,接着再在画布上绘制Android应用程序窗口的UI,最后再将画布的内容交给SurfaceFlinger服务来渲染.
...
↓
ViewRootImpl.draw()
↓
ViewRootImpl.drawSoftware()
↓
Surface.lockCanvas()
↓
android_view_Surface.nativeLockCanvas()
↓
surface.lock() //native 的lock
↓
GraphicBuffer.lock() //GraphicBuffer.cpp
↓
GraphicBufferMapper.lock() //GraphicBufferMapper.cpp , 应用程序窗口所使用的图形缓冲区一般都是在HAL模块Gralloc中分配的,因此,GraphicBufferMapper类的成员函数lock接下来就会调用成员变量mAllocMod所描述的一个HAL模块Gralloc的成员函数lock来获得参数andle所描述的一个图形缓冲区的地址,并且保存在输出参数vaddr中.
这一步执行完后,会回到 drawSoftware 函数里面继续往下执行: mView.draw,开始绘画
ViewRootImpl.drawSoftware()
↓
DecorView.draw()
↓
FrameLayout.draw()
↓
View.draw()
↓
ViewGroup.dispatchDraw()
↓
ViewGroup.drawChild()
到这里也就绘画完了,返回到 drawSoftware函数里面,执行surface.unlockCanvasAndPost(). 这里就是Java层的Surface类的成员函数unlockCanvasAndPost来请求SurfaceFlinger服务渲染这块画布里面所包含的一个图形缓冲区了.
ViewRootImpl.drawSoftware()
↓
Surface.unlockCanvasAndPost
↓
android_view_Surface.nativeUnlockCanvasAndPost //native
↓
surface.unlockAndPost //native
↓
GraphicBuffer.unlock
↓ Surface::queueBuffer //函数 queueBuffer 它主要就是向应用程序窗口的待渲染图形缓冲区队列中添加一个图形缓冲区,然后再请请求SurfaceFlinger服务来渲染这个图形缓冲区
GraphicBufferMapper.unlock