启动优化

启动优化

app启动流程

Click Event -> IP -> Process.start -> ActivityThread -> bindApplication -> LifeCycle -> ViewRootImpl

相关任务:

  • 冷启动之前
    1. 启动app
    2. 加载空白Window
    3. 创建进程
  • 随后任务
    1. 创建Application
    2. 创建主线程
    3. 创建MainActivity
  • 绘制任务
    1. 加载布局
    2. 布置屏幕
    3. 首帧绘制

相关工具的使用

参考:TraceView

参考:Systrace

启动时间测量方式

参考:启动时间测量方式

获取方法耗时

参考:获取方法耗时

启动优化核心思想

  • 子线程分担主线程任务,并行减少时间
  • 异步、延迟、懒加载

启动优化常规方案

一、优化小技巧

注意一:Theme 切换只是感觉上的快,实际启动时间并没有改变

注意二:会延长低版本(7.0或6.0以下)手机闪屏时间,需要综合考量是否需要在低版本使用 Theme

参考设置启动Theme

二、采用启动器实现并发初始化
  1. 阿里开源 alpha 启动器

    alpha 定位为异步启动框架。在执行启动任务时判断其是否是主线程执行,如果是则通过 handler#post 发送出去排队处理, 否则交给线程池处理。

  2. 更复杂图例启动器,适合负责场景

三、延迟初始化

在界面的真实数据展示里的UI显示后对可延迟初始化的任务进行初始化,如列表的第一条数据、可交互控件的显示等

  • android 6.0 之前:

    发送延迟消息对任务进行初始化

    缺点:无法确定延时的时长

  • android 6.0(含6.0) 使用 IdleHandler 在app闲置时初始化,可有效利用闲置时间:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class DelayInitDispatcher {
    private Queue<Task> mDelayTasks = new LinkedList<>();

    public DelayInitDispatcher addTask(Task task){
    mDelayTasks.add(task);
    return this;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void start(){
    Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
    @Override
    public boolean queueIdle() {
    if(mDelayTasks.size()>0){
    Task task = mDelayTasks.poll();
    // 执行 task
    }
    return !mDelayTasks.isEmpty();
    }
    });
    }
    }
四、懒加载

在需要用到的时候再进行加载

其它优化方案

一、Multidex 阶段提前加载 SharedPreference

Multidex官方文档

Multidex 加载阶段,由于此阶段更多是在 io 操作,所以可以充分利用此阶段的 CPU 加载 SP

Multidex 优化参考项目:MultiDex优化源码

注意:该方法只在低版本(Android 5.0 之前的平台,即 Dalvik 虚拟机)有效

二、启动阶段不启动子进程
  • 子进程会共享 CPU 资源,导致主进程 CPU 紧张
  • 注意:ApplicationonCreate 之前会启动 ContentProvider
三、提前异步加载类字节码

一个类的加载本身可能会涉及上千个其它类,可以提前异步加载类字节码

监控哪些类需要提前加载:可以替换掉系统的ClassLoader 用自己的 ClassLoader 来记录加载时间,按需选取需要异步加载的类

  • Class.forName() 只加载类本身及其静态变量的引用类
  • new 类实例 可以额外加载类成员变量的引用类
四、启动阶段抑制 GC

监控GC

支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」

五、更优的 CPU 资源调度

Hardcoder 让 App 充分调度系统资源

六、数据重排

支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能

Facebook Redex字节码优化工具

后期维护

  • 收敛修改涉及启动相关代码的权限:结合 CI 修改启动代码需要 Review 代码并测试通过才可合入

问题

面试官:今日头条启动很快,你觉得可能是做了哪些优化?