简述:

APP的启动流程:

  1. 加载启动App
  2. App启动之后立即展示出一个空白的Window
  3. 创建App的进程
  4. 创建App对象启
  5. 动Main Thread创
  6. 建启动的Activity对象
  7. 加载View
  8. 布置屏幕
  9. 进行第一次绘制

作为普通应用,App进程的创建等环节我们是无法主动控制的,可以优化的也就是Application、Activity创建以及回调等过程

Google给出的启动加速的方向:

  1. 利用提前展示出来的Window,快速展示出来一个界面,给用户快速反馈的体验;
  2. 避免在启动时做密集沉重的初始化(Heavy app initialization);
  3. 定位问题:避免I/O操作、反序列化、网络操作、布局嵌套等。
    备注:方向1属于治标不治本,只是表面上快;方向2、3可以真实的加快启动速度。

综上所述,应用的启动性能主要问题在以下两方面:

1)Application 初始化开销大

Application 的创建过程中,如果执行复杂的逻辑或者初始化大量的对象,将会影响应用的启动体验。比如:

  • 初始化 MainActivity 的状态信息;
  • 创建了大量临时变量导致 GC(GC 在 ART 下影响很小);
  • 执行磁盘 I/O操作(这甚至就会直接阻塞应用的执行);
  • 反序列化操作;
  • 多重循环等等。

2)Activity 初始化开销大

Activity 的创建中除了要避免 Application 创建中提到的问题,还需要注意以下问题:

  • 加载极其复杂的布局主线
  • 程中出现磁盘或网络 I/O
  • 加载和解码 Bitmap
  • 渲染多个 VectorDrawable 对象

常用解决方法:

  1. 层次过深:
    减少冗余、嵌套的布局层次。
    不绘制不可见的 UI,而是使用 ViewStub 对象在适当的时间布局绘制。
  2. 大量的资源初始化:
    调整资源初始化的位置,可以在不同的线程执行懒加载。
    延迟初始化组件、操作;
    加载部分视图,然后再加载大的位图和其他资源。
    使用网络数据缓存,对于多个接口的同时访问,可以合并
  3. 启动界面:
    使用 Activity 的 windowBackground 属性
    使用闪屏页
  4. 去掉无用代码、重复逻辑等
  5. 巧用线程:ThreadPoolExecutor比Thread更加高效、优势明显,但是特定场景下单个时间点的表现Thread会比ThreadPoolExecutor好:同样的创建对象,ThreadPoolExecutor的开销明显比Thread大;

其他优化,请参考文章:
android性能优化之布局优化android性能优化之内存优化