性能优化
Android性能优化-系列-头条祁同伟
Android性能优化典范-胡凯
- 流畅度
- 内存优化
- 电量、网络优化
- 安装包优化
一、流畅度优化
影响因素
- 界面过渡绘制
- 启动初始化卡顿
- 大数据在UI线程处理
- 动画消耗CPU资源
- 内存泄漏引发GC卡顿
- ANR
1、绘制相关
Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染。如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。
1.1、CPU、GPU
先经过CPU的计算加载到内存中,然后传递给GPU进行渲染
CPU
CPU:中央处理器(英文Central Processing Unit)是一台计算机的运算核心和控制核心。
- 顺序执行
- 进行计算、移位、存储等简单工作
GPU
GPU:英文全称Graphic Processing Unit,“图形处理器”。一个专门的图形核心处理器。
GPU是显示卡的“大脑”,决定了该显卡的档次和大部分性能,同时也是2D显示卡和3D显示卡的区别依据。2D显示芯片在处理3D图像和特效时主要依赖CPU的处理能力,称为“软加速”。3D显示芯片是将三维图像和特效处理功能集中在显示芯片内,也即所谓的“硬件加速”功能。
- 并行执行
- 图像、密码破译、大数据处理、金融分析
1.2、帧率、16ms
60fps作为App性能的衡量标准(人眼无法感知超过60fps的画面更新)
为了能够使得App流畅,我们需要在每一帧16ms以内处理完所有的CPU与GPU计算,绘制,渲染等等操作
- 1000ms/60fps(帧率) = 16ms
1.3、Android绘制检测工具
- Tracer for OpenGL查看过渡绘制
- Tools --> Layout inspector
- 开发者选项 --> GPU渲染分析
- 颜色区分过渡绘制的次数
- adb shell setprop debug.hwui.overdraw show
- adb shell setprop debug.hwui.overdraw false
1.4、过度绘制 OverDraw
屏幕上的某个像素在同一帧的时间内被绘制了多次。
在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。
Android性能优化之渲染篇
Android 过度绘制优化
使用clipRect()优化OverDraw
场景
避免多次绘制相同内容
- RecyclerView更新内容
- DiffUtil只更新有变化的内容
- 多重背景设置:Act、父、子等都设置各自背景
- 移除主题window背景 @null
- 移除不必要Background背景设置,如ViewGroup、View都各自设置的相同背景
- 按需显示占位图
避免绘制隐藏内容
- 自定义View:被覆盖部分本无需绘制
- ClipRect & QuickReject
- 使用clipRect()优化OverDraw裁剪矩形内需要绘制的界面
- canvas.quickreject()来判断是否没和某个矩形相交,从而跳过那些非矩形区域内的绘制操作
优化布局代码,减少View视图层级
- 减少视图的深度,来减少视图树的遍历过程
- ConstraintLayout等减少层级
- 使用ViewStub:动态布局内容,不显示时不绘制
- 慎用Alpha:先绘制透明度界面,再绘制颜色,绘制两次
- 标签:减少一个层级
2、App启动优化
应用启动时间-Dev
Android App 启动优化全记录
!!!!!面试官:今日头条启动很快,你觉得可能是做了哪些优化?
都9102年了,Android 冷启动优化除了老三样还有哪些新招?
启动流程
冷启动、温启动、热启动
冷启动流程
- 加载并启动应用
- 在启动后立即显示应用的空白启动窗口
- 创建应用进程
系统一创建应用进程,应用进程就负责后续阶段:
- 创建应用对象
- 启动主线程
- 创建主 Activity
- 扩充视图
- 布局屏幕
- 执行初始绘制
优化方向
视觉优化
- 默认启动Theme(windowBackground) --> 切换回正常Theme(setContent之前)
- ViewStub 替代在启动过程中不需要显示的 UI 控件(需要时再加载替换)
- 闪屏广告页面: 闪屏时间(固定) = App启动时间 + 闪屏时间(动态)
密集型应用初始化(Application/Activity)
- 立即主线程初始化
- 延迟主线程初始化
- 子线程初始化
MultipDex优化
通过redex重排列class文件
耗时分析和初始化顺序
启动耗时统计
- logcat: Displayed
- adb [-d|-e|-s ] shell am start -S -W
- reportFullyDrawn()
启动耗时工具分析
使用 CPU Profiler 检查 CPU 活动
Systrace + 函数插桩
Systrace系列
使用 Traceview 检查跟踪日志--已废弃
3、大数据在UI线程处理
数据处理量太大,一般分为三种情况
- 一是数据在UI 线程处理
- 二是数据处理占用 CPU 高,导致主线程拿不到时间片
场景优化
- 使用StringBuilder、SparseMap
- 使用缓存
- 放到子线程执行