启动的分类
冷启动
- 冷启动的耗时最多,基本启动流程如下:
热启动
- 热启动最快;因为没有 application的创建,也没有那么多的生命周期的调用。
- 流程如下:
温启动
- 较快。介于冷启动和热启动之间的速度。它只会重新走Activity创建的过程,不会走进程创建和application的创建过程。
启动相关任务和优化方向
- 冷启动之前的相关任务
这几项都是系统的任务,我们很难干预
- 启动app
- 加载空白window
- 创建进程
- 随后任务
这几项都是系统的任务,我们很难干预
- 创建application
- 启动主线程
- 创建MainActivity
- 加载布局
- 布置屏幕
- 首帧绘制
- 优化方向
Application 和 Activity 生命周期相关方向
启动时间测量方式
通过adb命令
adb shell am start -W [PackageName]/com.[packageName].SplashActivity
注意:前面部分时你的 applicationId 在 gradle中配置的 ,测试的就是debug的id,release的就是release的。后面是你对应启动activity的package+activity具体路径(必须是在AndroidManifest.xml中配置了如下配置)
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
代码打点的方式
- 代码打点可以考虑的点
- Application 的 attachBaseContext 作为开始点
- 第一个展示页面 onResume 用户可以交互为止
- 或者首个页面view开始绘制为止可以通过 View.OnPreDrawListener 或 addOnDrawListener 监听
优化思路(重点)
- 网上找了一张图 基本上就是这个思想来优化启动速度
- 代码检测耗时可以考虑的点
- 尽量减少代码侵入;可以通过 AOP 思想设计架构(通过AspectJ注解方式 或者 动态代理等思想)
- 线下可以通过工具来分析 TraceView;Systrace;AS的Profile等工具检测耗时的点;
- 通过adb直接获取代码执行时间的方式也可以粗略检测时间;但是实际意义不大,不太靠谱。
- 总结优化部分:
- 充分CPU并发性能,现在的设备基本都是多核的。可以根据CPU核数设计线程池。
- 为了代码简洁耦合度低,封装任务启动方式;
- 异步执行前需要考虑任务和任务之间是否有依赖关系
- 考虑可以切换线程池(切换IO密集型线程池还是计算密集型,还是必须new Thread)
- 是否必须主线程执行任务
- 可以在启动CPU利用率比较低的地方初始化SharedPreferences
- 可以通过 IdleHandler 在用户无操作时执行一些不重要任务,避免和主要任务抢占资源
- 可以通过Theme主题,让项目启动跳转没有空白页的感觉,从视觉效果让用户体验更好