56星座屋
当前位置: 首页 星座百科

android启动速度的优化(android性能优化二之卡顿优化)

时间:2023-06-01 作者: 小编 阅读量: 2 栏目名: 星座百科

相对于其他类型的性能指标,卡顿是能直接让用户产生视觉反馈的现象,比如App反应滞后于用户的操作,在严重的情况下会出现ANR。因此,开发人员平时写代码时必须要时刻提醒自己不要落入卡顿的陷阱之中。开发者可能忘记开启子线程,又同时做了同步请求等待,导致卡顿的发生。另外对于sp的存储,commit是同步操作,要在子线程中使用。2)线程间发生死锁,UI线程无法获取锁,导致无法继续执行。

阅读本文大概需要 5 分钟。

相对于其他类型的性能指标,卡顿是能直接让用户产生视觉反馈的现象,比如App反应滞后于用户的操作,在严重的情况下会出现ANR。关乎用户体验的大事,是很容易遭到用户吐槽的。因此,开发人员平时写代码时必须要时刻提醒自己不要落入卡顿的陷阱之中。

一. 卡顿原因

在罗列卡顿可能会发生的几个点之前,先简单介绍一下发生卡顿的原因。

在之前《handler系列》聊过,UI线程是基于queue中的message事件驱动的,事件 -> 执行 -> 下一个事件...,另一方面由于Android的帧率是60fps,也就是每16ms就会触发一次UI刷新,如果某个message的处理时间 > 16ms,就会导致接收到VSYNC信号的时候无法完成本次刷新操作,产生掉帧现象。

因此,从本质上来讲,我们必须让UI线程的任何事件在16ms之内解决战斗。

基于此,可能会导致卡顿的原因有三大类:

1)事件本身太耗时。

2)事件本身并不耗时,但需要等待别的地方返回耗时。

3)UI线程本身已经拿不到CPU资源来执行事件。

下面根据这三大类来分别具体细聊。

二. 耗时事件

这个很容易理解,就是把一些耗时业务逻辑直接写在了UI线程中,比如计算密集型的复杂计算,庞大的MD5计算,非对称RSA解密等。一般情况下,开发人员都不会犯这种错误,因为能够直接意识到计算量很大,本身就有警醒的作用。

三.耗时等待

1)网络I/O 同步请求

这种如果是在用以前比较老的网络库,比如URLConnection这种就需要开发人员自己来开启新的线程。开发者可能忘记开启子线程,又同时做了同步请求等待,导致卡顿的发生。但是现代网络库比如Okhttp,Retrofit已经帮我们准备好了线程池,一般不会再遇到。 

2)磁盘I/O 文件,数据库

一般的文件和数据库操作,大家可能都会自觉的在子线程中操作。但是值得一提的是SharedPreference的存储和读取,根据sp的设计,创建的时候会开启子线程把整个文件全部加载进内存,加载完毕再通知主线程,如果读取尚未结束,此时想获取某个key的值,主线程就必须等待加载完毕为止。

因此,如果你的sp文件比较大,那么会带来几个严重问题:

a)第一次从sp中获取值的时候,有可能阻塞主线程,使界面卡顿、掉帧。

b)解析sp的时候会产生大量的临时对象,导致频繁GC,引起界面卡顿。

c)这些key和value会永远存在于内存之中,不会被释放,占用大量内存。

所以千万不要把庞大的key/value存在sp中,比如把复杂的json当value。

另外对于sp的存储,commit是同步操作,要在子线程中使用。而apply虽然是在子线程执行的,但是无节制地apply也会造成卡顿,原因是每次有系统消息发生的时候(handleStopActivity,handlePauseActivity)都会去检查已经提交的apply写操作是否完成,如果没有完成则阻塞主线程。

3)跨进程Binder同步等待返回数据

四.CPU时间片

1)其他应用发生抢占CPU资源的情况,导致本应用无法获得CPU执行时间片。

2)线程间发生死锁,UI线程无法获取锁,导致无法继续执行。

3)频繁GC,内存抖动。GC的次数越多,消耗在GC上的时间就越长,CPU花在界面绘制上的时间相应就越短。

五. 分析

对于卡顿的分析手段,有很多工具可以使用,下面介绍几种。

1)TraceView

相比之下,TraceView是分析卡顿的神兵利器,它不仅能看出每个方法消耗的时间、发生次数,并且可以进行排序,直接从最耗时的方法开始处优化。

2)ANR-WatchDog

其原理简单来说就是开启一个子线程,设置tick = interval,然后每隔一个interval(可设置)就往UI线程queue中扔一个runnable,若UI线程没卡顿,则interval时间内会取出此runnable执行,即重置tick,那么下一个interval循环时根据检测此tick是否被重置来判断是否有卡顿发生。如果有,则打印此时的各个线程运行时的stack trace(可设置只打印主线程),以帮助定位。

3)AndroidPerformanceMonitor

AndroidPerformanceMonitor 是国人开发的一个检测卡顿的开源库,原名是BlockCanary,可以设置卡顿检测时间,debug模式下检测到的卡顿可以通知展示(基本和LeakCanary一样),这个在开发自测时很有用。

其基本原理稍有不同,它并没有采用新开线程自己往UI线程里扔runnable的这种普通思想。而是利用系统在loop()方法里取出message前后进行了log打印这一特点,来重写Printer的println(String)方法,根据message处理前后的时间差,来判断是否发生了卡顿。

public static void loop() { ... for (;;) { ... // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to "msg.target" "msg.callback": "msg.what); } msg.target.dispatchMessage(msg); if (logging != null) { logging.println("<<<<< Finished to "msg.target" "msg.callback); } ... }}

而且这个工具在卡顿发生时,收集的信息还比较丰富,包括基本信息,耗时信息,CPU信息,堆栈信息等。

4)ANR trace.txt

而对于ANR,每当测试跑monkey一晚下来,ANR必是log的重点关注对象,若存在ANR,测试肯定会开jira贴上log给开发解决。对于trace.txt的分析,有几个基本的点是需要重点关注的:

a)具体的call stack指向的具体代码,是否是卡顿发生的原因。

b)是否有lock相关的关键字,代表可能发生死锁。

c)是否有iowait字样,是否在UI线程发生了网络或者磁盘I/O。

d)CPU使用率是否很高,很高表示要么自身有计算密集型任务发生,要么在其他地方有抢占CPU资源的任务。很低说明非耗时计算导致,可怀疑死锁和I/O耗时等待。

六. 解决

只要通过log分析能够找到发生卡顿的代码,基本上可以宣告问题很容易解决了,因为无论是对于耗时事件还是耗时等待,都可以采取异步的方式搞定。

而对于被抢占时间片的场景:

1)如果是死锁,则需要fix发生死锁的漏洞;

2)如果排除了以上所有可能后,就可以怀疑卡顿是由于被其他应用抢占CPU或者GC抖动导致,这需要通过log中的CPU使用率,和memory相关的回收信息,或者通过在debug模式下场景复现,综合profiler来观察和确定。

对于无法找到定位但是能够复现的场景,还可以根据业务场景来log打印时间,逐步缩小可疑代码的范围,从而排查和定位原因。

七. 总结

总之,关于卡顿的分析,并不是所有卡顿发生了都能找到原因,相反,大量ANR发生后通过log分析来解决是非常棘手的,甚至根本无从下手。所以我的观点是,对于卡顿一定要在开发写代码时做好警惕,养成良好习惯才是正道,防范为主,解决问题为辅。

一切从android的handler说起(一)之message

一切从android的handler说起(二)之threadLocal

一切从android的handler说起(三)之UI线程不卡顿

一切从android的handler说起(四)之postDelay原理

一切从android的handler说起(五)之触摸事件模型

一切从android的handler说起(六)之生命周期来源

一切从android的handler说起(七)之Handler内存泄露


进入公众号,回复“程序员“可以领取一份计算机技术电子书福利合集

欢迎转发,关注公众号 肖晖

每天几分钟,掌握一个硬核面试知识点

    推荐阅读
  • 租房必须注意哪些问题(租房需要注意哪些问题)

    关于通勤时间,尽量把时间控制在:单程不超过半小时,来回不超过一小时。如有出现故障,应谨慎入住。如有损坏,应当要求房东维修好再入住。如有,应该明确了解具体情况。简单了解下室友,可以询问关于职业情况,生活习惯、日常作息等方面,主要是预防入住后,由于各方面的不同而受到打扰。

  • 北京老舍纪念馆门票多少钱 北京老舍故居门票多少钱

    北京老舍纪念馆门票多少钱?老舍纪念馆需要预约吗?预约入口在哪里?这些信息整理如下。

  • 星际战甲迅发电浆炮怎么得(星际战甲迅发电浆炮获得)

    星际战甲游戏中,迅发电浆炮的获得方法是玩家使用蓝图制作,玩家可在商店处购买迅发电浆炮的蓝图,迅发电浆炮是Gauss的标志性速射微型榴弹发射器,具有高暴击与高暴击倍率,同时也拥有着最短引爆距离的保险装置。

  • 铁线莲 铁线莲冬天可以室外过冬吗

    少数是宿根直立草本。复叶或单叶,常对生。花单生或为圆锥花序,萼片大,花瓣状,花色有蓝色、紫色、粉红色、玫红色、紫红色、白色等,雌、雄蕊多数。生长习性铁线莲喜肥沃、排水良好的碱性壤土,忌积水或夏季干旱而不能保水的土壤。耐寒性强,可耐-20低温。

  • 科普忘忧草和黄花菜是一种生物是什么意思(草和黄花菜是一种生物意思是什么)

    科普忘忧草和黄花菜是一种生物是什么意思?下面内容希望能帮助到你,我们来一起看看吧!科普忘忧草和黄花菜是一种生物是什么意思忘忧草又叫萱草、黄花菜、金针菜、萱草花、健脑菜、安神菜、绿葱、鹿葱花、萱萼,忘忧草和黄花菜是一种植物,只是名称上的不同。实际上我们常说的忘忧草和黄花菜都是说的同一种植物。他的中文学名叫做:萱草。

  • 好莱坞玫瑰情人(双性恋的好莱坞)

    今年25岁的她迥异于同辈的好莱坞女星,名声荣誉红毯粉丝狂热的爱,这些她都得到过,但另一边,诋毁出轨分手以及演技“面瘫”的骂名,屡屡让她成为众矢之的。07年接受法国杂志采访时朱莉大方承认了和日裔女模清水珍妮有过长达10年的交往。安娜·帕奎因在公开双性恋身份后引起舆论狂潮,但牙缝姐保持淡定气场,表示自己的性向早就不是秘密。

  • 春节放假过后的祝福(春节放假过后的祝福有哪些)

    春节放假过后的祝福锁定你的笑脸,拿一盒甜蜜,封装佳节记忆,祝愿你在新的起点上再接再厉,再造辉煌的!长假很快就结束了,已经陆续的开始进入到节后工作的状态中了,发条祝福短信送给你的朋友同事吧,希望他们可以慢慢适应,更上一层楼。早上一杯咖啡,赶走清晨疲惫;午后动动大腿,舒展身体酸累;晚上早点窝被,美梦甜甜入睡。节后上班,每天恢复一点,抖擞精神新一年!祝你新年工作步步高,家庭幸福平安绕。

  • 怎么煮汤圆不粘锅不露馅(煮汤圆有窍门牢牢记住)

    导语:煮汤圆有窍门,牢牢记住“4点”,汤圆不粘锅不露馅,圆润香甜正月十五元宵节,还有几天就到了,有些地方可以看花灯、猜灯谜,热闹非凡,也可能有些地方没有这些活动,但这一天大家都会在家吃汤圆,甜甜蜜蜜过元宵节。煮汤圆有窍门,牢牢记住“4点”,汤圆不粘锅不露馅,圆润香甜!更不能为了不煮破故意缩短时间,这样做会导致汤圆内部不熟。因此不能沸水煮汤圆,也不能凉水煮汤圆。

  • 红米手机怎么root(小米一键root工具)

    ROOT这个名词相信大部分安卓手机使用者应该比较熟悉,刷机前必须的操作,而现在安卓机的ROOT又不同于以前,现在大多需要刷入面具进行root。话不多说接下来进入干货教程:基本分为以下三步:1、解锁手机BL锁2、安装magisk软件并刷入magisk3、刷机或者安装自己需要的模块一、解锁手机BL锁:这个建议使用小米官方解锁工具解锁,新手不建议使用网上各种秒解锁工具对于小米用户来说,这是一个非常简单的事情。至此就完成小米手机刷面具ROOT操作了

  • 甘孜州五日自驾游线路推荐(甘孜州5日自驾游线路)

    线路一:D1康定-塔公寺-墨石公园景区-惠远寺-亚拉神山-八美镇(午餐)-炉霍(霍尔博物馆、郎卡杰唐卡基地)-洛若镇瓦须部落(住宿、晚餐)D2洛若镇-甘孜(午餐)-格萨尔王城-百利寺-白塔公园-汉人寺-马尼干戈镇(晚餐住宿)D3马尼干戈镇-玉龙拉措(新路海)-雀儿山-圣仙沟景区-门扎寺-圣地·帕翁卓勒景区-德格县(康巴文化中心博览园、印经院、更庆寺,午餐)-八帮寺-宗萨寺-多瀑沟景区-噶陀寺(以上