为了账号安全,请及时绑定邮箱和手机立即绑定

UI卡顿解决

标签:
Android

16ms原则:Android系统每隔16ms会发出VSYNC信号重绘我们的界面(Activity)。为什么是16ms, 因为Android设定的刷新率是60FPS(Frame Per Second), 也就是每秒60帧的刷新率, 约合16ms刷新一次。

卡顿:从用户角度说,App操作起来缓慢,响应不及时,列表滑动一顿一顿的,动画刷新不流畅等等一些直观感受。从系统角度来说,屏幕刷新的帧率不稳定,无法保证每秒绘制60帧,也就是说有掉帧的情况发生。

UI卡顿的原理:Android每16ms就会绘制一次Activity,通过上述的结论我们知道,如果由于一些原因导致了我们的逻辑、CPU耗时、GPU耗时大于16ms,UI就无法完成一次绘制,那么就会造成卡顿。

常见卡顿原因及解决方案:

一、过度绘制

去除不必要的背景色:

(1) 设置窗口背景色为通用背景色,去除根布局背景色

(2) 若页面背景色与通用背景色不一致,在页面渲染完成后移除窗口背景色

(3) 去除和列表背景色相同的Item背景色

布局视图树扁平化:

(1) 移除嵌套布局

(2) 使用merge、include标签

(3) 使用性能消耗更小布局(ConstraintLayout)

减少透明色,即alpha属性的使用:

(1) 通过使用半透明颜色值(#77000000)代替

二、UI 线程的复杂运算

UI线程的复杂运算会造成UI无响应, 当然更多的是造成UI响应停滞, 卡顿。产生ANR已经是卡顿的极致了

解决方案:运算阻塞导致的卡顿的分析, 可以使用 Traceview 这个工具。

三、频繁的 GC

频繁GC的原因:(1) 内存抖动(Memory Churn), 即大量的对象被创建又在短时间内马上被释放。(2) 瞬间产生大量的对象会严重占用 Young Generation 的内存区域, 当达到阀值, 剩余空间不够的时候, 也会触发 GC。即使每次分配的对象需要占用很少的内存,但是叠加在一起会增加 Heap 的压力, 从而触发更多的 GC。

解决方案:瞬间大量产生对象一般是因为我们在代码的循环中 new 对象, 或是在 onDraw 中创建对象等, 尽量不要在循环中大量的使用局部变量。


过度绘制检测

在Android手机的"系统设置"-->"开发者选项"-->"调试GPU过度绘制"-->"显示GPU过度绘制"中开启调试。

蓝色,淡绿,淡红,深红代表了4种不同程度的过度绘制(Overdraw)情况。

蓝色: 意味着overdraw 1倍,像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。

绿色: 意味着overdraw 2倍,像素绘制了三次。中等大小的绿色区域是可以接受的,你应该尝试优化、减少它们。

淡红: 意味着overdraw 3倍,像素绘制了四次,小范围可以接受。

深红: 意味着overdraw 4倍,像素绘制了五次或者更多。这是不可接受的,要修复它们。

我们的目标就是尽量减少红色 Overdraw,最理想的是蓝色,一个像素只绘制一次,合格的页面绘制是白色、蓝色为主,绿色以上区域不能超过整个的三分之一,颜色越浅越好。

解决方案:见文章的常见卡顿原因及解决方案

分析工具有

分析工具1:Android systrace

分析工具1:Method Profiling

还是打开DDMS,选中你的应用,点击第六个图标,
6

这边默认OK
7

点击OK开始抓取,接着滑动手机复现卡顿现象。最后再次点击第六个钮即可。
8

这里只看上图中的main就可以了。
9

点击main方法后会展开它的父方法(即调用main的方法)和它的子方法(即在main中调用的方法)。这里一般点击后面百分数较大的那个子方法(百分数表示方法执行所占用的cpu时间)。
接着要做的就是一步一步往下点,直到找到我们要找的耗时操作。

最后我们还是来到了这边
10

上图已经定位了decodeStream方法,再往下走也是进到framework没意义了。剩下的就是怎么将decodeStream放到主线程以外的线程的事情了。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消