安卓卡顿优化

一.卡顿及卡顿衡量标准:

1.卡顿:卡顿是人的一种视觉感受,比如滑动界面时,如果滑动不流畅就有卡顿额感觉;

2.衡量标准:FPS(帧率),每秒显示帧数,(Frames per Second),表示处理器每秒钟能更新的次数,高的帧率可以得到更流畅、更逼真的动画,一般来说,12fps大概类似于手动快速翻书的帧率,这明显感觉不够顺滑;30fps相对还可以接受,但是无法顺畅表现绚丽的画面内容;60fps则可以明显提升交互感和逼真感;再往上提升到75fps就不容易感觉有多大的流畅度提升感了;如果是VR设备需要高于75fps,才可能消除眩晕的感觉。

3.安卓卡顿原因:安卓系统每隔16ms发出VSYNC信号,触发对UI进行渲染,如果每次都能渲染成功,那么就达到了60fps的效果,即:1000ms/60fps~16ms。如果某个操作花费的时间超过了16ms,比如是24ms,那么在系统16ms发出信号要渲染UI的时候就会发生丢帧现象,那么用户在32ms内,看到的将是同一帧画面,少了16ms-32ms之间的那一帧。如果处理的时间超过一定的值大概5秒,那么就会卡死也就是ANR。

4.安卓每秒丢帧数(一秒共60帧)与卡顿情况关系:

0~10帧:流畅

10~20帧:较卡

20~40帧:很卡

40~60帧:卡死了

测试人员有专门工具可以检测

二.产生卡顿原因:

核心:分析在16ms中我们的应用做了什么工作,哪些工作阻止我们再16ms时更新界面;

以xml布局被绘制出来为例进行说明:

1.CPU负责把UI组件计算成多边形和纹理;2.OpenGL负责绘制图像;3.GPU栅格化需要显示内容并渲染到屏幕上

实际开发中,我们还加入交互,业务处理等工作,这些工作都需要在16ms中处理完成。

三.卡顿分析工具:

1.Profile GPU Rendering:(设置-开发人员选项-GPU呈现模式分析)

我们可以清楚的看到处理流程中各部分的耗时

详细分析可见:https://www.jianshu.com/p/0b90891771e9

2.过渡绘制查看工具使用:

https://www.jianshu.com/p/b1442924c203

3.使用Layout inspector 工具检查布局层级;老版本使用Hierarchy Viewer

https://blog.csdn.net/ziwang_/article/details/66970591

4.代码检查:android studio->Analyze->Inspect Code

https://www.jianshu.com/p/a0f28fbef73f

5.android studio-profiler-cpu监测

https://blog.csdn.net/wangjiang_qianmo/article/details/84103926

四.通用优化卡顿流程:

1.UI层优化:

①.过度绘制:在屏幕一个像素绘制多次

比如:不必要的background的设置,父布局和子布局使用的背景色是一样的,那就不要都设置背景色,以免造成过度绘制;

典型的问题:斗地主的每张牌叠放到一起,如果自定义view在onDraw中绘制每张牌的Bitmap,那么几张牌叠加的区域是过度绘制的,可以使用cavans.clipRect(注意在绘制每张牌的区域时,需要使用cavans.save及cavans.restore方法,保存和恢复cavans状态)方法来控制绘制区域,只绘制bitmap显示的区域,叠加的区域不绘制,则可以避免过度绘制;

详情可见github:https://github.com/zhangbenzhi/interviewDemo

②.层级过深,布局复杂

以下为通用优化流程:

1>减少不必要的层级,可以考虑使用ConstraintLayout等;

2>没有必要的父布局<merge>的使用;

3>在布局层次一样的情况下,建议使用LinearLayout替换RelativeLayout;性能高

4>如果使用LinearLayout导致层级变深,则使用RelaytiveLayout替换

5>某些View是Gone的然后代码控制显示的情况,则可考虑<ViewStub>的使用,布局界的懒加载

6>去除多余的背景色,对于有多层背景色的布局来说,留最上面的一层即可;

7>谨慎使用alpha,如果后渲染的元素设置有alpha值,那么这个元素就会和屏幕上已经渲染好的元素做blend处理,这样会导致不少的性能问题,特别是在列表的item中;

8>对于使用selector当背景的布局,可以将normal状态的color设置为透明;

9>去除xml中无用的命名空间

2.Lint代码问题查找:

①不要在onDraw方法中new对象;

②资源忘记回收;比如:定位没有关闭,数据库没有关闭;

③Handler使用不当导致内存泄露;postDelay(),在页面关闭时没有removeCallBacks

④没有使用SparseArray代替HashMap

⑤效率低下的weight

⑥可优化的布局(ImageView和TextView是否可以用一个TextView替换)

android studio->Analyze->Inspect Code 代码检查

3.优化App逻辑层

工具:android studio-profiler-cpu方法执行时长等监测

https://blog.csdn.net/wangjiang_qianmo/article/details/84103926

常见问题:主线程耗时大的函数,滑动过程中cpu工作问题,工具可以提供每个函数的耗时和调用次数,重点关注两种类型的函数:主线程占用cpu时间很长的函数,特别关注io操作(文件io、网络io、数据库操作等);主线程调用次数多的函数

好的做法:

①不要阻塞UI县城,占用CPU较多的工作尽可能放在子线程中执行;

②需要结合使用场景来选择不同的线程处理方案:

AsyncTask:为UI线程与工作线程之间进行快速切换提供的一种简单机制,适用于当下立即需要启动,但是异步执行的生命周期短暂的使用场景;

HandlerThread:为某些回调方法或者等待某些任务的执行设置一个专属的线程,并提供线程任务的调度机制;Loop消息分发处理;

ThreadPool:把任务分解成不同的单元,分发到各个不同的线程上,进行同时并发处理;有很多线程任务需要做;

IntentService:适用于执行由UI触发的后台Service任务,并可以把后台任务执行的情况通过一定的机制反馈给UI,执行完会自己回收,比自己控制要方便;

③如果大量操作数据库数据时建议使用批处理操作。如:批量添加数据;

五.综合案例:

1.xml看有没有无用的命名空间,删除掉;

2.xml用Layout Inspector层级查看器查看层级,是否有可以优化的层级;

3.xml看暂时gone掉的可否用<ViewStub>;

4.打开过度绘制查看工具看xml中是否有过度绘制,看是否有多余的背景

app冷启动速度优化:

5.Application onCreate()中第三方的初始化等操作优化,把没必要在主线程的放到子线程,可以考虑放到IntentService中;

放到子线程中时,有可能主线程在使用时,并没有在子线程中初始化完成,

解决方案1:可以考虑在IntentService中添加一个标志位,当初始化操作完成时,将标志位置为true;

解决方案2:使用观察者模式,在初始化完成时,被观察者通知观察者可以使用了

提高启动速度,可以使用android studio-Profile-CPU查看方法耗时,

6.首屏Activity渲染速度优化,提高启动速度

7.启动过程中白屏优化;SplashActivity的主题背景设置为启动页图片;Application的主题背景设置为默认应用背景;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值