性能优化|青训营笔记
这是我参与「第四届青训营 」笔记创作活动的第4天 性能优化有几个方向
- 流畅性优化
- 资源优化
- 稳定性优化
- 系统级优化
流畅性优化
如何解决卡顿
性能优化工具选型
GPU呈现模式
- 优点:无需二次开发,简单易用
- 缺点:不完全准确,不能得知卡顿的真正原因
Layertool
- 优点:清楚明了,可宏观感知ViewTree现状,也可定制分析overdraw,可快速找出布局问题
- 缺点:对UI性能瓶颈的分析不够精确
深入性能归因
- 初级 CPU profiler 中阶 TraceView 高阶 Systrace
CPU Profiler
打开CPU性能解析器的步骤
- 选择 View > Tool Windows > Profiler或直接点击右上角profiler图标
- 单击CPU时间轴中的任意位置以打开CPU Profiler
CPU Profiler的默认视图包括以下时间轴:
-
事件时间轴:显示应用中的 activity 在其生命周期内变化的过程,并指示用户与设备的交互
-
CPU 时间轴:实时显示CPU使用率和当前线程总数,可以通过沿时间轴的水平轴移动鼠标来检查历史CPU使用率数据 可以通过沿时间轴的水平轴移动鼠标来检查历史CPU使用率数据
-
线程活动时间轴:列出属于应用进程的每个线程,并使用下面列出的颜色在时间轴上指示它们的活动
性能优化方案
布局优化
布局优化就是减少布局文件层级,能加快程序绘制时间 使用布局应遵从以下原则:
- 如果既可以使用LinearLayout也可以使用RelativeLayout,尽量使用LinearLayout
- 如果布局中有嵌套布局,建议采用RelativeLayout
- 使用 include或 merge 标签和ViewStub,提取布局中公共部分的布局,可提高布局初始化效率
绘制优化
不要在onDraw方法中进行大量操作,不要在onDraw中创建新的对象,尽量不做耗时操作
内存泄漏优化
弄清楚什么会导致内存泄漏
- 不要在Acticity中声明静态变量,Activity无法完全销毁释放
- 单例设计模式引起的内存泄漏,当果一个对象不再使用时,单例对象还在持有该对象的引用,导致GC无法回收该对象。所以使用单例模式时,传入的context应该使用ApplicationContext
- 非静态内部类创建的静态实例造成的内存泄漏
- 不能在Activity中用非静态匿名内部类的方式引用hanlder,如果Looper还未执行完全部信息就销毁了Activity时,handler还持有Activity的引用,GC无法回收
响应速度优化
要在主线程中避免耗时操作,可以单独开一个线程进行耗时操作
listview优化
主要方式有:复用view,首先判断view是否为空,如果不为空直接引用,为空再创建 使用ViewHolder类,settag的方式保存布局的控件初始化信息,避免每次都去findviewbyid影响效率
Bitmap优化
很多时候并不需要加载原始尺寸的图片,可以通过BitmapFactory.Options加载缩小过的图片
线程优化
线程优化的思想就是采用线程池。线程池可以复用内部线程,避免不断创建和销毁线程带来的性能消耗,线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象的发生。