绘制原理

CPU复杂计算显示内容
GPU负责栅格化(UI元素绘制到屏幕上)
cpu换算成纹理,然后交给GPU来渲染

工具选择

Systrace

关注Frames
正常:绿色圆点
丢帧:黄色或红色
Alerts栏

Layout Inspector

Android自带工具 Tools->Layout Inspector
查看视图层次结构

Choreographer

获取FPS,线上使用,具备实时性
API16后

布局加载原理

性能瓶颈

布局文件解析:IO过程
创建View对象:反射

使用LayoutInflater.Factory统计控件耗时

LayoutInflater创建一个view的hook
定制创建view的过程:全局替换textview
必须执行在super.oncreate 之前,因为每个Activity只允许设置一次factory,super.oncreate已经设置过了

  1. LayoutInflaterCompat.setFactory2(LayoutInflater.from(this), new LayoutInflater.Factory2() {
  2. @Override
  3. public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
  4. long startTime=System.currentTimeMillis();
  5. View view=getDelegate().createView(parent,name,context,attrs);
  6. long endTime=System.currentTimeMillis();
  7. Log.d("codytest", name+"createView cost:"+(endTime-startTime));
  8. return view;
  9. }
  10. @Override
  11. public View onCreateView(String name, Context context, AttributeSet attrs) {
  12. return null;
  13. }
  14. });

AsyncLayoutInflater

异步Inflate,
WorkThread加载布局,回掉主线程
节约主线程时间
不能设置layoutinflater.factory(自定义解决)

Java 写代码

从根本上解决性能问题(没有IO和反射)
引入新问题:不便于开发,可维护性差

X2C介绍

github
保留XML优点,解决其性能问题
开发人员写XML,自动生成Java代码,进行加载
原理:APT编译期翻译XML为java代码

X2C使用
AnnotationProcessor ‘com.zhangyue.we:x2c-apt:1.1.2’
implementation ‘com.zhangyue.we:x2c-lib:1.0.6’
@xml(layouts=”activity_main”)

问题:
部分属性Java不支持
失去了系统的兼容(AppCompat)

绘制优化
扁平化布局
避免过度绘制
ViewStub
onDraw中避免创建大对象,耗时操作

模拟面试

你在做布局优化过程中用到了哪些工具

Choreographer 统计线上FPS
可以拿到整体的帧率
可以带到线上
拿到的帧率几乎是实时的

AOP,Hook
优化布局加载带来的时间消耗,需要知道每个布局加载的耗时

Systrace 可以很方便的看到每一帧的耗时,以及这一帧在布局中真正做了什么
Layout Inspector 很方便的看到每个布局的层级

布局为什么绘导致卡顿,你是怎么优化的

思路:讲解布局加载流程,从setcontent开始说起
IO、反射、遍历、重绘
异步Inflate、X2C、减少层级、减少重绘
AOP、监控

做完布局优化后有哪些成果产出

体系化监控手段:线下(获取到每个布局及每个控件加载耗时)+线上(获取FPS,知道在哪些界面容易丢帧)
指标:FPS、布局加载时间、布局层级
核心路径保障(核心路径review,以确保FPS、布局加载时间、布局层级等达到一个合理的状态)