android profiler启动分析,Android冷启动优化总结(四)——profile分析

小说明:冷启动在 Android 端分为两部分:

1. 进程启动 — application相关执行完毕

2. 第一个activity展示 — AdvertActivity进入activity栈,init,create,onCreate,onResume后展示。

这次我们分析并着手尝试优化下第一个部分

先看一下profile的耗时统计

437341cabbfd66402dc4d4091b22d11d.png

第一阶段:LoadedApk.makeApplication newApplication阶段,排除系统必须处理的流程,咱们自己可控部分又根据业务阶段拆分成3个小阶段在这个阶段会执行application的attachBaseContext和Application的构造方法

因为tinker的热修复机制,可以看到,这个阶段99.99%耗时都是在tinker的初始化和相关热修复准备上

application构造方法里,就YogaUtil.getProcessName() (第二列最后一个方法),获取进程名称,几毫秒是咱们自己的操作。

第二阶段:Activity.Thread.installContentProviders 创建contentProviders阶段,我们在这个阶段可以看到很多的contentProviders

YogaWorkManagerInitializer.onCreate

MobProvider.onCreate

SensorsDataContentProvider.onCreate

huawei.UpdateProvider

YouzanProvider

等等....

第三阶段:Instrumentation.callApplicationOnCreate applicationOnCreate阶段,这是application的onCreate执行,初始化三方sdk和我们进入app前需要提前准备工作执行的地方

后面所有页面的生命周期绑定准备工作

启动器(网络初始化,用户信息缓存初始化,三方sdk初始化 等等)

既然有3个阶段,那我们的优化工作就针对这三个阶段分别优化,各个阶段有各个阶段的优化方式:

第一阶段的相关优化

都是tinker的初始化,如果要优化,唯一的办法就是移除tinker热修复

tinker因为机制问题,需要再次启动app,才会生效热修复的代码,所以最近多半年热修复使用下来,结合咱们app线上实际情况,修复不够及时的需要解决

如果移除tinker,就要寻找tinker的替代品,选什么好?

首先我们移除tinker然后看profile的日志:

4e46c0f84312f8e70fa8193daa37169b.png 我们可以明显看到系统 classLoader后,本应该执行的tinker各种初始化肯定都没有了,只有Application构造方法里的YogaUtil.getProcessName(),第一阶段的耗时直接砍掉99.99%。

我们需要找到tinker的替代品,这个替代品需要满足两点:首先是能及时修复,其次是不能在Application里有重代码。而市面上免费开源的HotFix就3家,腾讯系,阿里系,美团;其中腾讯系都跟tinker差不多,而阿里系的免费开源AndFix已经从16年就停止更新了,最新版的HotFix是收费的;又要及时修复,我们只能看美团的robust。

在经过好几个小时的读文档,读demo,写demo后,最终实现了使用robust,说说使用感受:

相比于tinker就是简单,接入简单,配置简单,修改简单,拆分包简单,打补丁也简单。

每次冷启动都要加载对应的补丁包,这种机制带来几个问题,一个是application要加载补丁文件(这个还好就是异步加载补丁,比起tinker要少太多工作了),一个是要像个机制能让对应的补丁文件在对应的包上加载。如果要替换,要考虑清楚这两点,并且服务端补丁包下发接口也需要配合修改。(ps: 关于robust的实现,在另外的文档说明)

第二阶段优化

因为都是contentProvider,所以我移除contentProvider,考虑是否可以换一种实现方式。

移除YogaWorkManagerInitializer后:

android profiler启动分析,Android冷启动优化总结(四)——profile分析_第1张图片

可以看到,YogaWorkManagerInitializer的onCreate不仅没执行,系统紧跟在其后的attachInfo也没有执行了,看了下源码流程,每一个contentProvider的onCreate执行后,系统都要对应执行一段attachInfo做其它操作,所以干掉一个provider不仅仅是干掉自己方法的耗时,同时连带系统的这部分时间也会跟着节省下来。

移除三方sdk的Provider,这个目前shareSdk的Provider没有找到移除的方式,后续看其他三方的provider是否可以移除,移除后再试下功能。

第三阶段优化

之前所有的任务是顺序执行,耗时长,有一个版本更改成启动器的方式多线程初始化。

在多线程初始化的基础上,还能做的就是监听每个线程的执行时间,如果任务时间分配不均匀,可以再通过合并or拆分启动任务的方式,让时间最长的任务链减轻任务量,挪到负担轻的任务链里。

总结

如果这三个阶段都可以按上述方式改动的话,对于application这里,通过profile占比,基本还可以缩小50%-70%左右的启动时间。

拖地先生,从事互联网技术工作,在这里每周两篇文章,聊聊日常的实践和心得。往期推荐:

如果对你有帮助,让大家也看看呗~

你可能感兴趣的:(android,profiler启动分析)