Fork me on GitHub

Android性能优化

性能优化的目标

  • 流畅的体验
  • 稳定
  • 省电/流量
  • 安装包小

如何达到目标

当然是性能优化啦!

布局优化

  1. 如果父控件有颜色,同时也是自己需要的颜色,那么就不必在子控件加背景颜色
  2. 如果每个子控件的颜色不太一样,而且可以完全覆盖父控件,那么就不需要再父控件上加背景颜色
  3. 尽量减少不必要的嵌套
  4. 能用LinearLayout和FrameLayout,就不要用RelativeLayout,因为RelativeLayout控件相对比较复杂,测绘也想要耗时
  5. 使用include和merge增加复用,减少层级
  6. ViewStub按需加载,更加轻便
  7. 复杂界面可选择ConstraintLayout,可有效减少层级

include 可以提高布局的复用性,方便开发,有人说这个没有减少布局的嵌套吧,对,include确实没有,但是include需要和merge搭配

merge 的布局取决于父控件是哪个布局,使用merge相当于减少了自身的一层布局,直接采用父include的布局,当然直接在父布局里面使用意义不大,所以会和include配合使用,既增加了布局的复用性,也减少了一层布局嵌套。

ViewStub 它可以按需加载,什么意思?用到时再加载,不用时就想静静。对于一些进度条,提示信息等等长时间才用一次的功能,使用ViewStub是极其合适的。

绘制优化

  1. onDraw中不要创建新的局部对象
  2. onDraw方法中不要做耗时的任务

内存优化

内存泄漏指的是程序不再使用的对象无法被GC识别,这样就会导致这个对象一直留在内存当中,占用内存空间。

造成内存泄漏的对象存在于

  1. 集合类泄漏
  2. 单例/静态变量造成的内存泄漏
  3. 匿名内部类/非静态内部类
  4. 资源未关闭造成的内存泄漏

启动速度优化

app启动分为冷启动(Cold start)、热启动(Hot start)和温启动(Warm start)三种。

  • 冷启动(Cold start)
    冷启动是指应用程序从头开始:系统的进程在此开始之前没有创建应用程序。冷启动发生在诸如自设备启动以来首次启动应用程序或自系统终止应用程序以来。
  • 热启动(Hot start)
    在一个热启动中,系统都会把你的Activity带到前台。如果应用程序的Activity仍然驻留在内存中,那么应用程序可以避免重复对象初始化、布局加载和渲染。
  • 温启动(Warm start)
    温启动包含了冷启动时发生的一些操作,与此同时,它表示的开销比热启动少,有许多潜在的状态可以被认为是温暖的开始。

启动中优化的建议

  1. 利用提前展示出来的Window,快速展示出来一个界面,给用户快速反馈的体验
  2. 避免在启动时做密集沉重的初始化(Heavy app initialization)
  3. 避免I/O操作、反序列化、网络操作、布局嵌套等

安装包优化

  • 删除无用的资源
  • 自己用XML写Drawable,图片占用空间较小
  • 重用资源
  • 压缩PNG和JPEG文件
  • 使用WebP文件格式
  • 使用矢量图形
  • 代码混淆
  • 插件化
    比如功能模块放在服务器上,按需下载,可以减少安装包大小

耗电优化

谷歌的做法,并没什么感觉

  • 使用JobScheduler调度任务
  • 懒惰法则

谷歌推荐使用JobScheduler,来调整任务优先级等策略来达到降低损耗的目的。JobScheduler可以避免频繁的唤醒硬件模块,造成不必要的电量消耗。避免在不合适的时间(例如低电量情况下、弱网络或者移动网络情况下的)执行过多的任务消耗电量。

具体功能:

  1. 可以推迟的非面向用户的任务(如定期数据库数据更新);
  2. 当充电时才希望执行的工作(如备份数据);
  3. 需要访问网络或 Wi-Fi 连接的任务(如向服务器拉取配置数据);
  4. 零散任务合并到一个批次去定期运行;
  5. 当设备空闲时启动某些任务;
  6. 只有当条件得到满足, 系统才会启动计划中的任务(充电、WIFI…)。

懒惰法则

  • 减少
    你的应用程序可以删除冗余操作吗?例如,它是否可以缓存下载的数据而不是重复唤醒无线电以重新下载数据?
  • 推迟
    应用是否需要立即执行操作?例如,它可以等到设备充电才能将数据备份到云端吗?
  • 合并
    可以批处理工作,而不是多次将设备置于活动状态吗?例如,几十个应用程序是否真的有必要在不同时间打开收音机发送邮件?在一次唤醒收音机期间,是否可以传输消息?

ListView 和 Bitmap优化

ListView优化

  • 针对ListView优化,主要是合理使用ViewHolder
  • 对数据进行分段或者分页加载,也可以优化性能

Bitmap优化

  1. 对图片质量进行压缩
  2. 对图片尺寸进行压缩
  3. 使用libjpeg.so库进行压缩

响应速度优化

响应速度优化的核心思想是避免在主线程中做耗时操作,把耗时操作异步处理。

线程优化

线程优化的思想是采用线程池,避免在程序中存在大量的Thread。

其它优化

  1. 避免创建不必要的对象
  2. 针对特定场景(不需要访问对象的字段)首选静态
  3. 对常量使用static final
  4. 使用增强的for循环语法
  5. 避免使用浮点数

参考文章大佬大佬