应用的启动可分为冷启动、温启动、热启动三种模式,其中冷启动的耗时最长,一般来说启动优化针对的就是冷启动模式;
冷启动大致的过程:
- 点击应用图标后,Launcher进程向SystemServer进程发起启动请求;
- SystemServer验证通过后进程调用Zygote进程fork出应用进程;
- 应用进程启动后,调用SystemServer进程启动开屏Activity;
- 开屏页Activity加载window渲染页面;
在这些阶段当中,可以由应用开发者控制的部分主要在Application的创建和开屏页的创建过程;Application的创建耗时一般是由于做了太多初始化工作,开屏页耗时一般出在页面的创建和渲染上,所以针对这两点可做的优化主要有:
- 初始化调用延后; 首先将需要初始化的内容分类:
- 必须在开屏页创建前完成初始化的部分:这一部分仍然需要放在Application的onCreate或attachBaseContext内执行,需要注意是否为应用的主进程;
- 需要在非应用主进程初始化的部分:一些使用了多进程能力的库,或者修复多进程兼容问题时,需要在其对应进程内执行初始化;
- 必须在主线程初始化的部分:一般是一些UI相关的初始化,比如Fressco库的初始化;可以放在开屏页渲染完成后,利用开屏的等待时间的这2~3秒完成;
- 可以在子线程初始化的部分:同样放在开屏页渲染完成后,利用开屏的等待时间的这2~3秒完成;
- 可以在使用前初始化的部分:一些不常用的,或者不需要马上使用的功能,在第一次使用时再做初始化;
- 简化开屏页视图
- 利用主题中的windowsBackgroud设置启动页样式;
- 优化setContentView视图内容;
除以上几点外,我们还可以通过提升CPU运行效率、暂停GC回收、提升应用进程优先级等方式提升启动速度,不过这些方法在不同机型上存在差异。微信团队开源的Hardcoder提供针对不同ROM的优化启动接口,但是很多接口只对微信有效,具体能达到什么效果由手机厂商决定,只能算是一种补充的尝试吧。
测试冷启动的时间:
从Android 4.4开始,我们可以通过Logcat中的Tag为ActivityTaskManager的日志中找到到从启动进程到Activity绘制完成的时间:
I/ActivityTaskManager: Displayed 包名/开屏页Activity名: 具体耗时
可以使用adb命令获取更多信息:
adb shell am start -W 应用包名/开屏页activity名
输出的信息包含:
- waitTime:进程准备到调用启动开屏页Activity的耗时;
- thisTime:创建及渲染开屏页Activity的耗时;
- totalTime:总耗时;