性能优化总览
电量优化
- 优化代码,减少不必要的操作,或者合并操作,减少设备活跃时间,比如一次性的请求网络数据,一次性的IO。
- 延迟操作,通过监听系统广播、WorkManager等方式监听设备充满电之后再搞事情。
网络优化
- 直接使用IP地址,避免漫长的DNS解析过程
- 连接复用,避免多次建立连接(okHttp自带的keep-alive和多路复用)
- 对数据压缩处理(gzip)
- 采用json,protobuf,甚至graphQL减少数据体积和传输频次
- 本地缓存数据,避免频繁请求接口
- 识别设备网络状态,在2/3/4G流量状态下传输低清图片
- 使用webP格式图片
UI卡顿优化
layout加载问题
正常的流程是在主线程先IO读取并递归解析一个xml文件,再通过反射创建View对象,效率很低,遇到复杂的layout,甚至可能引发ANR。
- 使用约束布局,减少布局嵌套,减少递归;
- 使用
AsyncLayoutInflater
异步加载,不会阻塞主线程; - 使用注解处理器+javaPoet在编译时生成View文件。(掌阅x2c原理)
重复绘制问题
- 使用约束布局,减少布局嵌套
- 去除看不见的背景图片
- 减少alpha的使用,使用alpha会导致View绘制两次,可使用ARGB色值替代
卡顿问题
- 自定义View的onDraw优化
- 内存抖动频繁GC
排查工具
- Systrace
- profile
- adb
apk体积优化
- lint检查无效资源
- 混淆minifyEnabled
- 资源排除
- 图片压缩,webP,
VectorDrawable
- 使用tint前台改色复用图片
- 指定本地化语言
- 指定NDK
- 本地库压缩,在manifast文件中为application指定
android:extractNativeLibs = true
内存优化
数据结构优化
ArrayList
- 初始化长度定位0,避免第一次add时扩容,空间换时间
- 增删时使用LinkedList,查询时转换成ArrayList
- 避免在中间插入和移除,这样会遍历改变下标,非常耗时,可以从末尾操作
- 使用HashMap替代,HashMap增删快,查询快
HashMap
- 预估长度避免扩容
- 长度为2的整数倍,避免哈希冲突
- 使用SpaceArray替代,其核心是二维数组,并采用二分法提高查询效率。
崩溃监控
- Thread.setDefaultUnCauthExceptionHandler
- linux错误信号
ANR监控
通过监听linux错误信号,经判断找出ANR错误,然后上报。