APP冷启动优化:如何使用好工具,腾讯面试算法题

}




requestLayout会scheduleTraversals预先占位一个异步消息,用于接收并doScheduleCallback触发的VSYNC信号,这样可以保证之后插入的消息都被延期处理,从而Window被添加后,UI绘制任务第一时间执行。



void scheduleTraversals() {

if (!mTraversalScheduled) {

    mTraversalScheduled = true;

    <!--异步消息-->

    mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();

    <!--插入绘制请求,触发VSYNC-->

    mChoreographer.postCallback(

            Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

}




等待VSYNC消息回来后,撤离异步消息栅栏,第一时间处理UI绘制:



![5dc2b9664bef88aa8590047a92f2b37c.png](https://img-blog.csdnimg.cn/img_convert/5dc2b9664bef88aa8590047a92f2b37c.png)



image



可以看到,这个逻辑基本上是挨着addView执行。所以可以认为是Resume之后第一个比较靠前的系统调度异步消息,那么只要在onResume之后插入插入一条消息,其实就可以监控到首帧渲染,如下图所示。



![2964d6e3a6ca8a8a15927b4f14db0f68.png](https://img-blog.csdnimg.cn/img_convert/2964d6e3a6ca8a8a15927b4f14db0f68.png)



image



网上也有一些其他的实现,比如onAttachedToWindow或者OnWindowFocusChange后发消息,或者直接监听,原理差不多。



![b710ae18e92ac66e289c9b8ae3181720.png](https://img-blog.csdnimg.cn/img_convert/b710ae18e92ac66e289c9b8ae3181720.png)



image



综上所述,可以认为在Resume之后插入一个消息即可。有了指标,那是否达标?如何采集?基线呢?可以参考业界做法,采集方式可以无入侵打点,而优秀基线可以认为:



优秀=秒开




如果发现不达标,接下来要做的就是定位+优化,这个时候就体现分析工具的重要性,其实上述的原理分析就已经借助Studio自带的Profiler工具,在理解流程上事半功倍。



二、如何定位当前性能问题

============



冷启动每个阶段的耗时可以通过多种工具、方式来定位:可以用的有Debug.startMethodTracing跟踪,也可以利用perfetto/systrace来查看,甚至还可以用Studio自身的Profiler跟踪,每种方式都有自己的优势,可配合选择使用。



Debug.startMethodTracing 适合查看UI线程的耗时函数

--------------------------------------



Debug.startMethodTracing是通过应用插桩来生成跟踪日志,做到对方法的跟踪。但是启用剖析功能后,应用的运行速度会减慢,所以,不应使用剖析数据确定绝对时间,最大的作用是用在对比上,可以对比之前,或者对比周围函数。具体用法:



private void startTrace() {

File file = new File(getApplication().getExternalFilesDir("android"), "methods.trace");

Debug.startMethodTracing(file.getAbsolutePath(), 100 * 1024 * 1024);

}

<!-注意配对使用–>

private void stopTrace() {

Debug.stopMethodTracing();

}




对于冷启动:进程启动时开启监听,在合适节点配对停止即可,之后导出.trace文件在Studio中分析,可以看到关键函数耗,Studio提供了多种模式,Flame Chart、Top Down、Bottom Up、Event,不同的模式侧重点不同。定向分析的时候,可以分段锁定范围,比如冷启动可分几个阶段排查,进程创建、Application初始化、Activity的创建、create、resume、draw等,先选定Main线程,然后将范围限制定Application阶段,如下下:



*   Flame Chart:更侧重直观反映函数耗时严重程度

    



![83e09cd0646556dfc52c2b3f8431165f.png](https://img-blog.csdnimg.cn/img_convert/83e09cd0646556dfc52c2b3f8431165f.png)



image



比如上图,浅黄色部分其实就是需要重点关注的部分,耗时最多的函数,会最先展示,更加方便定位严重问题,大致定位问题后,就可以用Top Down 进一步看细节。



*   Top Down:更侧重自顶向下详细排查

    



利用Top-Down模式可以更精确观察函数耗时与调用堆栈,更加清晰,如下在Application初始化阶段,可以清醒看到函数调用顺序、耗时等,



![abc66e6dfe8201c0d3bbfafcd11365fc.png](https://img-blog.csdnimg.cn/img_convert/abc66e6dfe8201c0d3bbfafcd11365fc.png)



image



对于冷启动,重点排查耗时函数,尝试将非核心逻辑从UI线程中移除。同理对于闪屏Activity的onCreate跟onResume阶段所做的处理类似



![e9546d7da1840e60af28baa0bacec4e9.png](https://img-blog.csdnimg.cn/img_convert/e9546d7da1840e60af28baa0bacec4e9.png)



image



从图中就很容下发现,有些Flutterboost、埋点Json解析类的耗时操作被不小心关联进了Activit的启动流程中,拖慢了冷启动速度,那就可以放到非UI线程中处理,或者延后处理。



*   Bottom Up:一种平铺的模式,

    



![df1caf7cec08cf14980fac80b0d889ac.png](https://img-blog.csdnimg.cn/img_convert/df1caf7cec08cf14980fac80b0d889ac.png)



image



这个模式个人用的不多,罗列的函数太多,没有层次,可能单独看排名靠前的几个有些收益。



依赖profiler基本能定位哪些函数导致了冷启动速度慢,但是这些函数可能并非自己耗时严重,也许是会因为调度或者锁的原因导致慢,这个时候perfetto/systrace会提供更多帮助。



三、perfetto/systrace:大局与调度

=========================



perfetto地址及使用文档



perfetto/systrace是官方提供另一种性能分析工具,其中perfetto可以看做是systrace的升级版。相比MethodTracing代码插桩,无法具体到每个方法,但可以提供全局性能概览,可以更快定位问题范围,而且perfetto/systrace在全局任务调度、系统调用上更具优势,MethodTracing多少对于性能有些影响,而perfetto/systrace借助系统本身lOG,可以降低自身带来的影响,用perfetto看一下冷启动的流程,如下:



![27c12b179f642f7c96a38be30cff7fb7.png](https://img-blog.csdnimg.cn/img_convert/27c12b179f642f7c96a38be30cff7fb7.png)



image



如图,首先你就能直观的看到那些阶段的耗时比较严重,然后定向分析即可,将时间段收缩,放大观察:



![06b4a0f55b7a590c9b6a7c8b37bd6388.png](https://img-blog.csdnimg.cn/img_convert/06b4a0f55b7a590c9b6a7c8b37bd6388.png)



image



可以直观看出Activity启动时蓝色标记的资源解析耗时过长,定向排查后发现图大



Name res/BKC.xml

Category null

Start time 1s 309ms 568us 459ns

Duration 42ms 35us 682ns

Slice ID 2465




适当将图缩小,降低加载成本,经过优化缩短到8ms



Name res/BKC.xml

Category null

Start time 964ms 602us 749ns

Duration 8ms 260us 261ns

Slice ID 11851

type internal_slice




再比如,对于有些阶段,UI线程莫名的睡眠,其实可以比较方便的查看是什么因素导致的,如下:



![aedbeff75a049b74c20076e07c7e7de9.png](https://img-blog.csdnimg.cn/img_convert/aedbeff75a049b74c20076e07c7e7de9.png)



image



如上所示,在当前阶段,UI线程因为没有获取锁进入了睡眠,之后,被另一个线程唤起了,这就可以排查到底是哪个地方有问题,是否可以避免,大概的使用方式就是如此。



四、对于整体冷启动优化效果:用perfetto看比较直接

============================



优化前:1261ms



![90055cf0ba289783de008e147c7651a6.png](https://img-blog.csdnimg.cn/img_convert/90055cf0ba289783de008e147c7651a6.png)



image



优化后:439ms



![31554bd2a73a759b2fd9a5495ae0ec68.png](https://img-blog.csdnimg.cn/img_convert/31554bd2a73a759b2fd9a5495ae0ec68.png)



image



所用的优化除了上面的措施还有部分如下措施等:



*   延迟非必要receiver的注册

    

*   闪屏广告Layout布局按需加载

    

*   锁优化,进程线程间阻塞优化

    



所用的优化除了上面的措施还有部分如下措施等:核心原则 UI线程不做耗时操作



*   延迟非必要receiver的注册

    

*   闪屏广告Layout布局按需加载

    

*   锁优化,进程线程间阻塞优化

    



总结

==



BUG是必然的,优化是持久的,如何用好工具是关键的。



作者:看书的小蜗牛  

链接:https://www.jianshu.com/p/867b7c45828c



**友情推荐:**



[Android 开发干货集锦]( )



至此,本篇已结束。转载网络的文章,小编觉得很优秀,欢迎点击阅读原文,支持原创作者,如有侵权,恳请联系小编删除,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!



![7ef2ec784da460ffc244482cb2d94a48.png](https://img-blog.csdnimg.cn/img_convert/7ef2ec784da460ffc244482cb2d94a48.png)



_点击阅读原文,为大佬点赞!_





**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/64ac245965a26c80166af7ce0b73e5c5.png)
![img](https://img-blog.csdnimg.cn/img_convert/2a6be1c382f2c676196989911d85d802.png)
![img](https://img-blog.csdnimg.cn/img_convert/00280245416fa9916d6330217bb77fc4.png)
![img](https://img-blog.csdnimg.cn/img_convert/9baae1e08f6d8eca051ba778145ed5b1.png)
![img](https://img-blog.csdnimg.cn/img_convert/02ad3aa6272701207c506cd3d53f2253.png)
![img](https://img-blog.csdnimg.cn/img_convert/202f4373df2898a7294e407f5da630bc.png)
![img](https://img-blog.csdnimg.cn/13f2cb2e05a14868a3f0fd6ac81d625c.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)**
![img](https://img-blog.csdnimg.cn/img_convert/bdaacd932f82b8cde67cb02970656844.png)



## 最后

题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

**【Android思维脑图(技能树)】**

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

![Android开发8年,阿里、百度一面惨被吊打!我是否应该转行了?](https://img-blog.csdnimg.cn/img_convert/96bff6d976ce078265075514a05453ff.webp?x-oss-process=image/format,png)

**【Android进阶学习视频】、【全套Android面试秘籍】**

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展

后

题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

**【Android思维脑图(技能树)】**

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中...(img-NBHRT9N5-1711924668570)]

**【Android进阶学习视频】、【全套Android面试秘籍】**

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展

> **本文已被[CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》]( )收录**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值