目录
一、冷启动定义
[图片上传失败...(image-50a13f-1575207142191)]
简而言之:冷启动是APP进程未启动时,用户启动APP到启动Activity显示的时候,需要消耗的时间。两大核心消耗时间无非就是Appliction onCreate时间消耗,以及Splash Activity渲染页面前的时间消耗。
这边需要澄清一个点是:APP安装第一次启动,和APP进程杀掉再重新启动,启动的时间是有不一样的地方的,这中间有一个MultiDex的过程(attachBaseContext中)。
google的官方文档定义的是到Launcher Activity的时间,但通常的APP中会有一个splash Activity,所以有时候,我们的冷启动定义会稍微修正下,会计算到真正和用户相关的Activiy,即splash之后的MainActivity。
我以微信为例,用户从桌面点击图标开始,会经过 4 个关键阶段...
二、 冷启动和热启动
冷启动:
在启动应用时,系统中没有该应用的进程,这时系统会创建一个新的进程分配给该应用;
热启动:
在启动应用时,系统中已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程还是保留在后台);
三、冷启动、热启动的区别
冷启动:系统没有该应用的进程,需要创建一个新的进程分配给应用,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。 热启动: 从已有的进程中来启动,不会创建和初始化Application类,直接创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。
四、冷启动时间的计算
API19 之后,系统会出打印日志输出启动的时间; 冷启动时间 = 应用启动(创建进程) —> 完成视图的第一次绘制(Activity内容对用户可见);
五、冷启动流程
Zygote进程中fork创建出一个新的进程; 创建和初始化Application类、创建MainActivity; inflate布局、当onCreate/onStart/onResume方法都走完; contentView的measure/layout/draw显示在界面上;
总结:
Application构造方法 –> attachBaseContext() –> onCreate() –> Activity构造方法 –> onCreate() –> 配置主题中背景等属性 –> onStart() –> onResume() –> 测量布局绘制显示在界面上。
六、冷启动的优化
减少在Application和第一个Activity的onCreate()方法的工作量; 不要让Application参与业务的操作; 不要在Application进行耗时操作; 不要以静态变量的方式在Application中保存数据; 减少布局的复杂性和深度;
七、常用优化方案
闪屏优化:
针对用户点击图标后白屏或者无反应现象:
Android系统在启动APP的时候,会将第一个启动的Activity的背景拿出先展示出来,若Activity的window背景没有设置,那默认就是白屏;若设置了透明,就会点击后看起来没有反应。
我们可以通过自定义style来解决这个问题,如下:
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/img_splash</item> </style>
[图片上传失败...(image-630713-1575207142191)]
业务优化:
梳理初始化阶段的耗时业务初始化,看看是否有耗时业务可以懒加载
[图片上传失败...(image-b2e193-1575207142191)]
线程优化:
[图片上传失败...(image-5b5130-1575207142191)]
代码块
线程池数量设置:
-
CPU密集型任务
尽量使用较小的线程池,一般为CPU核心数+1
因为CPU密集型任务使得CPU使用率很高,若开过多的线程数,只能增加上下文切换的次数,因此会带来额外的开销。
-
IO密集型任务
可以使用稍大的线程池,一般为2*CPU核心数+1
IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候去处理别的任务,充分利用CPU时间。
对io密集型:
在这篇如何合理地估算线程池大小?文章中发现了一个估算合理值的公式
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:
最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目
可以得出一个结论:
线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。
以上公式与之前的CPU和IO密集型任务设置线程数基本吻合。
锁检查:
GC优化:
系统调用优化:
[图片上传失败...(image-3fb153-1575207142191)]
I/o优化
[图片上传失败...(image-2aa7f1-1575207142191)]
数据重排:
[图片上传失败...(image-e3ed55-1575207142191)]
类重排
https://github.com/facebook/redex
[图片上传失败...(image-94e8e-1575207142191)]
资源重排:
https://mp.weixin.qq.com/s/79tAFx6zi3JRG-ewoapIVQ
仅供内部使用,未经授权,切勿外传
暂无赞赏,鼓励一下
?
+1