1Android绘制原理及工具选择
绘制原理
CPU负责计算显示内容
GPU负责柵格化(UI元素绘制到屏幕上)
系统每16ms发出VSync信号出发UI渲染(每帧在16ms内完成)
大多数Android手机屏幕刷新频率60Hz(人眼和大脑极限)
优化工具
1、Systrace --之前用它查看了内存消耗情况;现在关注Frames
正常:绿色原点,丢帧:黄色或者红色
Alerts栏

2、Layout Inspector
AS自带
可查看层次结构


3、Choreographer
获取FPS,线上使用,具备实时性
API16+
Choreographer.getInstance().postFrameCallback
实际效果

2Android布局加载原理

性能瓶颈
布局文件解析:IO过程
创建View对象:反射过程
LayoutInflater.Factory介绍
LayoutInflater.创建View的一个Hook
定制创建View的过程:全局替换自定义的TextView等。


Facory2多了一个parent参数

Factory是Hook点
3优雅获取界面布局耗时
常规方式
背景:获取每个界面加载耗时
实现:复写SetContentView 手动埋点
不够优雅
有侵入性
AOP/ArtHook方式
AOP实现
切Activity的setContentView



第一个224ms 第二个10ms
ArtHook方式 略
切Activity的setContentView
获取任意控件耗时
低侵入性
用到LayoutInflater.Factory是创建View的一个hook
代码:



上图创建View 其实是系统hoot 创建了TextViewCompat 实现了兼容
注意:LayoutInflaterCompat要在super.onCreate(..)之前设置!!之后无效
4异步Inflate实战
背景介绍
布局文件解析慢:IO过程
创建View对象:反射过程(比new 慢3倍)
侧面缓解AsyncLayoutInflater实战
简称异步Inflate
1WorkThread加载布局
2回调主线程
3节约主线程时间
先导包:谷歌默认的但并没加载到里面
com.android.support:asynclayoutinflater

创建了一个Handler,一个线程。创建过程都在子线程。
使用AsyncLayoutInflater将会失去系统兼容效果!!要自己写。
总结
侧面缓解

5布局加载优化实战
背景介绍
IO操作、反射
AsyncLayoutInflater只是缓解

布局加载优化实战






6视图绘制优化实战
测量:确定大小
布局:确定位置
绘制:绘制视图
性能瓶颈
每个阶段都耗时
自顶向下的遍历
触发多次
优化布局层级及复杂度
准则
1减少View树层级
2宽而浅,避免窄而深
1、ConstraintLayout
实现几乎完全扁平化的布局
构建复杂布局性能更高
具有Relative和LinearLayout的特性
2、不嵌套使用RelativeLayout
3、不在嵌套的LinearLayout中使用weight
4、merge标签:减少一个层级,只能用于根View
避免过度绘制
一个像素最好只被绘制一次
调试GPU过度绘制
蓝色可接受(绿色粉色红色)
1去掉多余背景色,减少复杂shape使用
2避免层级叠加
3自定义View使用clipRect屏蔽被遮盖View绘制


去掉background后

自定义view要如下修改


其他
Viewstub:高效占位符、延迟初始化
onDraw中避免:创建大对象、耗时操作
TextView优化:(有专项讲解)
7模拟面试
布局优化中用到哪些工具?
不同场景不同工具
统计线上FPS --》Choreographer 实时的
获取加载耗时 AOP/Hook
线下使用 systrace 、Layout Inspector
布局为什么导致卡顿,你怎么优化的
IO、反射、遍历、重绘
异步Inflate、X2C,减少 层级、重绘
AOP、监控
做完布局优化有哪些成果
体系化的监控手段:线下+线上
指标:FPS、加载时间、布局层级
上线前对核心路径保障review
网友评论