(一)UI的绘制过程:
相关文章:
再次总结:在ActivityThread启动时,首先将VIew交给了WindowManager,然后WindowManager调用addView(view,layoutParams)方法,将所有相关对象保存起来。然后进行UI的绘制:先测量布局,在进行布局的摆放,当所有的布局测量摆放完毕之后,进行绘制。
总结:
- (1)、在ActivityThread启动时,通过一些列的调用,首先将我们的VIew交给了WindowManager,然后调用windowManager.addView(view,layoutParams)(第一个参数是view,第二个参数是布局参数)。
- (2)、进入addView之后我们发现了一段这样的代码,他将视图,和参数还有我门的一个ViewRoot对象都用了容器去装在了起来,那么在此处我们可以得出,是将所有的相关对象保存起来。
- (3)、UI绘制先回去测量布局,然后在进行布局的摆放,当所有的布局测量摆放完毕之后,进行绘制。
UI是如何绘制的?
在ActivityThread启动时, 我发现在加载handleLaunchActivity方法调用performLaunchActivity方法之后又调用了一个handleResumeActivity在这里我发现了绘制流程的开始
通过前面的流程我门知道,onCreate之行完成之后,所有资源交给WindowManager保管
在这里,将我们的VIew交给了WindowManager,此处调用了addView
进入addView之后我们发现了一段这样的代码,他将视图,和参数还有我门的一个ViewRoot对象都用了容器去装在了起来,那么在此处我门可以得出,是将所有的相关对象保存起来
mViews保存的是View对象,DecorView
mRoots保存和顶层View关联的ViewRootImpl对象
mParams保存的是创建顶层View的layout参数。
而WindowManagerGlobal类也负责和WMS通信
而在此时,有一句关键代码root.setView,这里是将我们的参数,和视图同时交给了ViewRoot,那么这个时候我们来看下ViewRoot当中的setView干了什么
终于在这里让我发现了让我明白的一步
在这里我门会看到view.assignParent的设置是this, 那么也就是说在view当中parent其实实际上是ViewRoot
那么在setContentView当中调用了一个setLayoutParams()是调用的ViewRoot的
而在ViewRoot当中发现了setLayoutParams和preformLayout对requestLayout方法的调用
在requestLayout当中发现了对scheduleTraversals方法的调用而scheduleTraversals当中调用了doTraversal的访问,最终访问到了performTraversals(),而在这个里面,我发现了整体的绘制流程的调用
当前里面依次是用了
UI绘制先回去测量布局,然后在进行布局的摆放,当所有的布局测量摆放完毕之后,进行绘制。
至此整体UI绘制过程我们就已经非常清楚了。
我门可以根据这种绘制的流程来操作自己的自定义组件。
。。。。。结束。。。。。
(二)常见的UI优化手段以及原理:
一般来讲,布局出现问题的原因有两点:
- 一是布局层次不合理;
- 二是布局存在过度绘制;
解决方案:
- 1、使用Hierarchy Viewer工具检测
- 2、使用include 和merge标签减少复用布局而产生的布局嵌套,使用ViewStub懒加载减少渲染元素
- 3、诊断过度绘制,优化过度绘制