性能优化

性能优化
文章图片
性能的四个方面

  • 优化目的
    1. 尽量减少主线程操作
    2. 尽量减少GC
  • 优化流程
  1. 首先通过SM(帧率)对App的流畅度进行测试评估(引入APM情况下)。
  2. 然后从最简单的App UI层入手,优化App的UI来提升流畅度。
  3. 接着通过lint静态扫描发现一部分代码中存在的性能问题,然后进行优化。
  4. 最后再进一步深入的分析和解决App逻辑层和IO层存在的问题
1. 布局优化
  1. 减少布局复杂度
    • 尽量减少不必要的嵌套
      使用include和merge增加复用,减少层级
      使用ViewStub按需加载
      3层以上的复杂页面选择使用ConstraintLayout
    • 在相同层级结构相同并且界面效果相同时,选择性能高的ViewGroup
      FrameLayout>LinearLayout>RelativeLayout,同时也可以自定义ViewGroup来减少计算量。
  2. 【性能优化】避免过渡绘制(开启GPU过度渲染)
    • 去掉不必要的背景
    • 使用Space标签
    • 不必要的alpha值设置可以解决同一视图被多次绘制的问题
2. 绘制优化
  1. onDraw方法中不要做耗时的任务
    onDraw方法中不要做耗时的任务,也不做过多的循环操作,特别是嵌套循环,虽然每次循环耗时很小,但是大量的循环势必霸占CPU的时间片,从而造成View的绘制过程不流畅。
  2. onDraw中不要创建新的局部对象
    onDraw()中不要创建新的局部对象,因为onDraw()方法一般都会频繁大量调用,就意味着会产生大量的临时对象,不仅占用过的内存,而且会导致系统更加频繁的GC,大大降低程序的执行速度和效率。
  3. 避免不必要的绘制
    自定义控件时canvas.clipRect可以解决只刷新固定区域的问题,可参考DrawerLayout
3. 内存优化
  1. 避免内存泄露
    • 集合类内存泄漏(持有空对象引用)
    • 单例/静态变量造成的内存泄漏
    • 匿名内部类/非静态内部类
    • 资源未关闭造成的内存泄漏
  2. 避免内存抖动(Memory Minotor)
    • 避免在for循环中new大对象或数组
    • 避免在onDraw()方法中new大对象或数组
  3. 避免OOM
    • 避免内存泄露
    • Bitmap尽量使用Glide加载
    • Bitmap优化(质量压缩、尺寸压缩)
  4. 避免使用枚举
    • 使用常量,使用@IntDef
      Enum 到底占多少内存
      正确使用枚举
4. 启动速度优化(trace)
  1. 冷启动优化
    • 利用提前展示出来的Window,快速展示出来一个界面,给用户快速反馈的体验;
    • 避免在启动时做密集沉重的初始化(Heavy app initialization)
    • 避免I/O操作、反序列化、网络操作、布局嵌套等
  2. Activity启动优化
5. 代码优化 选择正确的算法和数据结构应始终是我们的首要任务,以提高代码效率。
  1. 避免创建不必要的对象
  2. 方法特定场景下使用静态方法
  3. 对常量使用static final
  4. 使用增强的for循环语法(RandomAccess例外)
  5. 避免使用浮点数
  6. 避免使用反射
    ...
6. 包大小优化
  1. 代码混淆
  2. 资源优化
  3. 方法数优化
  4. 插件化
7. 耗电优化
  1. 使用JobScheduler调度任务
  2. 使用懒惰法则

    推荐阅读