启动优化
app启动流程
Click Event -> IP -> Process.start -> ActivityThread -> bindApplication -> LifeCycle -> ViewRootImpl
相关任务:
- 冷启动之前
- 启动
app
- 加载空白
Window
- 创建进程
- 启动
- 随后任务
- 创建
Application
- 创建主线程
- 创建
MainActivity
- 创建
- 绘制任务
- 加载布局
- 布置屏幕
- 首帧绘制
相关工具的使用
启动时间测量方式
获取方法耗时
启动优化核心思想
- 子线程分担主线程任务,并行减少时间
- 异步、延迟、懒加载
启动优化常规方案
一、优化小技巧
注意一:Theme
切换只是感觉上的快,实际启动时间并没有改变
注意二:会延长低版本(7.0或6.0以下)手机闪屏时间,需要综合考量是否需要在低版本使用 Theme
二、采用启动器实现并发初始化
-
alpha 定位为异步启动框架。在执行启动任务时判断其是否是主线程执行,如果是则通过 handler#post 发送出去排队处理, 否则交给线程池处理。
三、延迟初始化
在界面的真实数据展示里的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
22public class DelayInitDispatcher {
private Queue<Task> mDelayTasks = new LinkedList<>();
public DelayInitDispatcher addTask(Task task){
mDelayTasks.add(task);
return this;
}
public void start(){
Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
public boolean queueIdle() {
if(mDelayTasks.size()>0){
Task task = mDelayTasks.poll();
// 执行 task
}
return !mDelayTasks.isEmpty();
}
});
}
}
四、懒加载
在需要用到的时候再进行加载
其它优化方案
一、Multidex
阶段提前加载 SharedPreference
在 Multidex
加载阶段,由于此阶段更多是在 io
操作,所以可以充分利用此阶段的 CPU
加载 SP
Multidex
优化参考项目:MultiDex优化源码
注意:该方法只在低版本(Android 5.0 之前的平台,即 Dalvik 虚拟机)有效
二、启动阶段不启动子进程
- 子进程会共享
CPU
资源,导致主进程CPU
紧张 - 注意:
Application
的onCreate
之前会启动ContentProvider
三、提前异步加载类字节码
一个类的加载本身可能会涉及上千个其它类,可以提前异步加载类字节码
监控哪些类需要提前加载:可以替换掉系统的ClassLoader
用自己的 ClassLoader
来记录加载时间,按需选取需要异步加载的类
- Class.forName() 只加载类本身及其静态变量的引用类
- new 类实例 可以额外加载类成员变量的引用类
四、启动阶段抑制 GC
支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
五、更优的 CPU 资源调度
六、数据重排
支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能
后期维护
- 收敛修改涉及启动相关代码的权限:结合 CI 修改启动代码需要 Review 代码并测试通过才可合入