安卓应用的冷启动和热启动

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/hnlgzb/article/details/86665472

参考两位大佬的博客

https://blog.csdn.net/addisonko/article/details/51207772

https://blog.csdn.net/sinat_20059415/article/details/79942710


应用的冷、热启动感觉跟电脑的冷、热启动类似的。


直接copy,留个纪念


1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。
2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。

 


一、.应用启动流程

在安卓系统上,应用在没有进程的情况下,应用的启动都是这样一个流程:当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上,所以直到这里,应用的第一次启动才算完成,这时候我们看到的界面也就是所说的第一帧。

所以,总结一下,应用的启动流程如下:

Application的构造器方法——>attachBaseContext()——>onCreate()——>Activity的构造方法——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上。

这块需要对activity启动有整体上的认识才行。

2 冷热启动特点

1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,因为一个应用从新进程的创建到进程的销毁,Application只会初始化一次。

上面说的启动是点击app的启动图标来启动的,而另外一种方式是进入最近使用的列表界面来启动应用,这种不应该叫启动,应该叫恢复

二、测量应用启动的时间

在上面这个启动流程中,任何一个地方有耗时操作都会拖慢我们应用的启动速度,而应用启动时间是用毫秒度量的,对于毫秒级别的快慢度量我们还是需要去精确的测量到到底应用启动花了多少时间,而根据这个时间来做衡量。


https://blog.csdn.net/addisonko/article/details/51207772

连接博主说的一些优化操作

减少应用启动时的耗时

针对冷启动时候的一些耗时,如上测得这个应用算是中型的app,在冷启动的时候耗时已经快700ms了,如果项目再大点在Application中配置了更多的初始化操作,这样将可能达到1s,这样每次启动都明显感觉延迟,所以在进行应用初始化的时候采取以下策略: 

1、在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时操作的初始化,一些数据预取放在异步线程中,可以采取Callable实现。
2、对于sp的初始化,因为sp的特性在初始化时候会对数据全部读出来存在内存中,所以这个初始化放在主线程中不合适,反而会延迟应用的启动速度,对于这个还是需要放在异步线程中处理。
3、对于MainActivity,由于在获取到第一帧前,需要对contentView进行测量布局绘制操作,尽量减少布局的层次,考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中避免做耗时操作。
遵循上面三种策略可明显提高app启动速度。
 


自己测试

1.冷启动:初始点击应用图标的时候,系统没有该应用进程。

2.热启动:不是初次点击该图标,或者说在recent tasks里面有这个进程。

按楼上博主的意思:

3.恢复,就叫恢复吧:从直接从recent tasks点击出来的。

测试时间

adb shell am start -W com.example.xxxx/.activity.MainActivity

1.冷启动

C:\Users\lenovo>adb shell am start -W com.example.lenovo.xxxx/.activity.MainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.lenovo.xxxx/.activity.MainActivity }
Status: ok
Activity: com.example.lenovo.xxxx/.activity.MainActivity
ThisTime: 555
TotalTime: 555
WaitTime: 573
Complete

2.按back键启动

C:\Users\lenovo>adb shell am start -W com.example.lenovo.xxxx/.activity.MainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.lenovo.xxxx/.activity.MainActivity }
Status: ok
Activity: com.example.lenovo.xxxxx/.activity.MainActivity
ThisTime: 132
TotalTime: 132
WaitTime: 143
Complete

3.按home键启动

C:\Users\lenovo>adb shell am start -W com.example.lenovo.xxxx/.activity.MainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.lenovo.xxxxx/.activity.MainActivity }
Warning: Activity not started, its current task has been brought to the front
Status: ok
Activity: com.example.lenovo.xxxx/.activity.MainActivity
ThisTime: 66
TotalTime: 66
WaitTime: 72
Complete

三种不一样的状态,花费的时间不一样。

冷启动>back键后打开>home键后打开,

这种命令行的方式打开,测试的时间,跟实际操作的差别,应该不会太大。

从recent tasks点开的方式,就是home键后打开 应该是一样的。、

如果要测试实际情况,那就打log来看了,比如前面一个博主,把application oncreate/activity 周期方法都用log的方式打印出来了,再加个时间就好了。

猜你喜欢

转载自blog.csdn.net/hnlgzb/article/details/86665472