冷启动优化相关问题
什么是冷启动
冷启动的定义
冷启动就是启动前,系统中没有该应用的任何进程信息
对应的是第一次打开应用和杀掉应用进程后再次进入应用。
冷启动 / 热启动的区别
热启动:
就是用户按了返回键或home键退出应用后,马上又重新启动应用
区别:
定义不同:
冷启动启动前,没有该应用的进程,需要重新创建该应用的进程
热启动启动前,已经有该应用的进程,不需要重新创建应用的进程,应用进程是保存在后台的。
启动特点不同:
冷启动:
由于会重新创建进程,因此会先初始化application,在初始化Activity,然后再进行测量,布局和绘制等等,最后显示在界面上
热启动:
由于后台已经存在应用进程,不会重新创建application,而是直接走Activity,进行测量布局绘制等操作,然后显示在界面上
因为一个应用从创建到销毁,其application只初始化一次。
这里通过代码描述一下:
这里application里面做了一个延迟操作,延迟三秒。
此时如果是冷启动会等待三秒后才能显示mainactivity,热启动不会有延迟。
冷启动时间的计算
从应用启动,创建进程开始算起,到完成视图的第一次绘制(即Activity内容对用户可见)为止.
冷启动的流程
-
Zygote进程中fork创建出一个新的进程
-
创建和初始化Application类,创建MainActivity类
-
inflate布局、当onCreate/onStart/onResume方法都走完
-
ContentView的measure/layout/draw显示在界面上
Application的构造方法 --> attachBaseContext() --> onCreate() --> Activity的构造方法 --> onCreate() --> 配置主题中背景等属性 --> onStart() --> onResume() --> 测量布局绘制显示在屏幕上。
如何对冷启动进行优化
-
减少onCreate方法的工作量
-
不要让application参与业务操作
把每个业务模块都用到的数据可以在application里面初始化,但是不能把业务相关的放在application里初始化。 -
不要在application里进行耗时操作
比如在application里面在一些IO操作,从sd卡中读取数据,这些操作是不能放在application中的。 -
不要以静态变量的方式在application中保存数据
因为静态变量的生命周期和app生命周期一致。可能会造成内存泄漏或者数据安全等问题。 -
布局 / mainThread
尽量减少布局的复杂性,在布局view的测量过程中,是非常耗时的。布局的层级越庞大,app就需要越多的时间去填充它。
为了节约时间,不填充那些不需要在启动时就展示的view,这里可以通过ViewStub来实现。需要的时候按需加载
mainThread中做资源的初始化,也会减慢启动速度,所以在这里可以通过懒加载,或者将资源的加载放到子线程中。