本文参考了
hyczlf(https://blog.csdn.net/LF_HYCZ/article/details/76034457)
joye123(https://blog.csdn.net/joye123/article/details/79425398)
jeanboydev(https://blog.csdn.net/freekiteyu/article/details/77862670)
等文章,如若侵权,请联系删除。

在我们开发使用的APP中经常会看到程序动画卡顿的现象,
Android 应用的卡顿,丢帧等,这些影响用户体验的因素绝大部分都与 16ms 这个值有关。 下面我们来讨论下 UI 渲染方面影响应用流畅性的因素。

16ms

  • 12 fps(帧/秒):由于人类眼睛的特殊生理结构,如果所看画面之帧率高于每秒约 10-12 fps 的时候,就会认为是连贯的。
    早期的无声电影的帧率介于 16-24 fps 之间,虽然帧率足以让人感觉到运动,但往往被认为是在快放幻灯片。
    在1920年代中后期,无声电影的帧率提高到 20-26 fps 之间。
  • 24 fps:1926 年有声电影推出,人耳对音频的变化更敏感,反而削弱了人对电影帧率的关注。因为许多无声电影使用 20-26 fps
    播放,所以选择了中间值 24 fps 作为有声电影的帧率。 之后 24 fps 成为35mm有声电影的标准。
  • 30 fps:早期的高动态电子游戏,帧率少于每秒 30 fps 的话就会显得不连贯。这是因为没有动态模糊使流畅度降低。
    (注:如果需要了解动态模糊技术相关知识,可以查阅 这里)
  • 60 fps:在实际体验中,60 fps 相对于30 fps 有着更好的体验。
  • 85 fps:一般而言,大脑处理视频的极限。

所以,总体而言,帧率越高体验越好。 一般的电影拍摄及播放帧率均为每秒 24 帧,但是据称《霍比特人:意外旅程》是第一部以每秒 48 帧拍摄及播放的电影,观众认为其逼真度得到了显著的提示。

目前,大多数显示器根据其设定按 30Hz、 60Hz、 120Hz 或者 144Hz 的频率进行刷新。 而其中最常见的刷新频率是 60Hz。 这样做是为了继承以前电视机刷新频率为 60Hz 的设定。 而 60Hz 是美国交流电的频率,电视机如果匹配交流电的刷新频率就可以有效的预防屏幕中出现滚动条,即互调失真。

正如上面所述目前大多数显示器的刷新率是 60Hz,Android 设备的刷新率也是 60Hz。只有当画面达到 60fps 时 App 应用才不会让用户感觉到卡顿。那么 60fps 也就意味着 1000ms/60Hz = 16ms。也就是说 16ms 渲染一次画面才不会卡顿。

知道了上面的知识,那么我来总结一下Ui卡顿的原因以及解决方案。

UI卡顿的根本原因
通过上述的结论我们知道,如果由于一些原因导致了我们的逻辑、CPU耗时、GPU耗时大于16ms,UI就无法完成一次绘制,那么就会造成卡顿。简单的一句话就是:卡主线程了。
比如说,在16ms内,发生了频繁的GC:

然而追其应用层的话,就是常见View的内存抖动问题以及主线程太耗时(CPU占用)两个原因。
内存抖动
常见的内存抖动的原因是就UI中View的绘制过程中创建了大量对象,又大量回收,导致频繁的发生GC,所以会出现Ui卡顿。解决方案就是减少对象的创建以及页面的频繁刷新。
解决实例:使用String的时候将其改为StringBudiler来避免内存频繁创建,TextView和ImageView的组合可以用TextView的setLeftDrawable或者setRightDrawable来添加图片。使用weakRefrence弱引用来创建图片对象。

注意,GC是无法避免的,我们要避免的是频繁的GC,因此这里的优化实质上是内存优化。
方法耗时(CPU占用)
当在主线程绘制过程中出现大量占用CPU的耗时操作时,也会出现Ui卡顿。解决方案就是更换方式使方法不耗时。
原因实例:
1.Json数据解析耗时(Cache类)
2.文件操作(获取所属渠道名称)
3.Binder通信(获取系统属性(mac地址))
4.正则匹配(Hybird 通信)
5.相机操作:初始化、预览、停止预览、释放(反扫)
6.组件初始化(推送)
7.循环删除、创建View(更多页面)
8.WebView首次初始化
解决实例:修复优先级顺序:异步 > 缓存 > 替代方案 > 保持原状。

接下来说说View绘制的内部问题。
比如说过度绘制,如果绘制的层数过高,导致主线程在16ms中无法将整个页面绘制完成就会出现掉帧的情况,从而导致Ui卡顿。
过度绘制
我们的Android手机能过通过:开发者选项 -> 调试GPU过度绘制,来打开该功能,来查看是否出现了过度绘制。

原色:没有过度绘制
蓝色:过度绘制1次
绿色:过度绘制2次
粉色:过度绘制3次
红色:过度绘制4次或更多
请注意,这些颜色是半透明的,因此,您在屏幕上看到的确切颜色取决于您的界面内容。

可以通过此功能查看哪些页面的布局层级过深。
处理方案也有很多种:

去除不必要的背景色
1.设置窗口背景色为通用背景色,去除根布局背景色。
2.若页面背景色与通用背景色不一致,在页面渲染完成后移除窗口背景色
3.去除和列表背景色相同的Item背景色

布局视图树扁平化
1.移除嵌套布局
2.使用merge、include标签
3.使用性能消耗更小布局(TableLayout、ConstraintLayout)

减少透明色,即alpha属性的使用
1.通过使用半透明颜色值(#77000000)代替

其他
1.使用ViewStub标签,延迟加载不必要的视图
2.使用AsyncLayoutInflater异步解析视图

我们常见的Ui卡顿其实在很多情况下是无法发现原因的。所以为了快速找到卡顿原因,就要利用检测工具。
常见的检测工具有:
1.Hierarchy Viewer(分析Ui性能)
2.手机开发者自带GPU呈现模式(考核Ui性能)
3.TraceView (代码层面分析性能问题)
生成 trace 文件有三种方法:

  • 使用代码
  • 使用 Android Studio
  • 使用 DDMS

4.Systrace (检测 App 的性能)
具体的使用方法我来贴一个门,有意者查看原博来看。
Android-性能优化-UI优化

Android优化之UI优化相关推荐

  1. Android产品研发(二十一)--Android中的UI优化

    转载请标明出处:一片枫叶的专栏 上一篇文章中我们讲解了Android产品研发过程中的代码Review.通过代码Review能够提高产品质量,增强团队成员之间的沟通,提高开发效率,所以良好的产品开发迭代 ...

  2. Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题

    一.Android:Socket客户端开发 创建一个工程 我们要做的是按下按键之后,去往服务器 (服务器) 或者我们自己写的服务器 ,给他发送一些预定好的东西 然后打开操作界面 然后修改一下 你要发送 ...

  3. Android 天气APP(十三)仿微信弹窗(右上角加号点击弹窗效果)、自定义背景图片、UI优化调整

    上一篇:Android 天气APP(十二)空气质量.UI优化调整 天气预报详情,逐小时预报详情 新版------------------- 一.适配器点击监听 二.页面实现 三.天气预报详情弹窗 四. ...

  4. Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化

    上一篇:Android 天气APP(十)下拉刷新页面天气数据 逐小时天气预报.UI优化 新版------------------- 一.UI优化 二.逐小时天气预报 ① 添加逐小时天气API ② 使用 ...

  5. Android高手笔记-屏幕适配 UI优化

    Android高手笔记-屏幕适配 & UI优化 屏幕与适配 由于Android碎片化严重,屏幕分辨率千奇百怪,而想要在各种分辨率的设备上显示基本一致的效果,适配成本越来越高: 屏幕适配究其根本 ...

  6. Android 天气APP(十二)空气质量、UI优化调整

    上一篇:Android 天气APP(十一)未来七天的天气预报.逐小时预报.UI优化 空气质量数据.UI优化 新版------------------- 一.自定义View 二.修改XML布局 三.添加 ...

  7. android 7双排设置菜单,联想拯救者电竞手机优化横屏UI 设置菜单呈左右双排显示...

    原标题:联想拯救者电竞手机优化横屏UI 设置菜单呈左右双排显示 过去的直板手机都由物理按键来实现操作,按键加上屏幕后手机整体偏长,而进入大屏智能机时代,按键的位置被屏幕取缔,但长方形的屏幕设计依然得到 ...

  8. Android性能优化之启动优化实战篇,积累总结

    目录 (1)必备Java基础 (2)设计思想解读开源框架 (3)360°全方位性能优化 (4)Android框架体系架构 (5)NDK模块开发 (6)Flutter学习进阶 (7)微信小程序开发 一. ...

  9. 【Android 性能优化】布局渲染优化 ( CPU 渲染优化 | 减少布局的嵌套 | 测量布局绘制时间 | OnFrameMetricsAvailableListener | 布局渲染优化总结 )

    文章目录 一. 减少布局嵌套 二. 布局渲染时间测量 1. FrameMetrics 使用流程 2. FrameMetrics 参数解析 3. FrameMetrics 代码示例 三. 布局渲染优化总 ...

最新文章

  1. linux 系统装中文输入法 fcitx
  2. golang struct 切片数组去重
  3. python模块介绍-locustio:性能测试工具locustio
  4. SAP ABAP和Java里的弱引用(WeakReference)和软引用(SoftReference)
  5. WINFORM應用程式的主進入點和清除資源
  6. 信息学奥赛C++语言:趣味整数4(水仙花数)
  7. label mpchart 饼图_Android MPChart—饼图-Go语言中文社区
  8. 小程序 request:fail ssl hand shake error 问题解决方法
  9. makefile obj文件路径_makefile中包含的文件的路径
  10. MetaMask/metamask-extension/mascara 的运行实现
  11. 易灵思FPGA-报告总结篇
  12. 用canvas写 看你有多色 游戏
  13. 7-34 查询水果价格 (15 分)
  14. python setup.py install与python setup.py develop的区别
  15. Sendmail配置以及验证成功
  16. 启动Jenkins时报错,localhost拒绝了我们的连接请求
  17. C#获取目录下所有文件的列表——最白话,手把手教你做系列。
  18. C#像素鸟(独自一鸟闯天下)
  19. SQL语句--CASE函数写法的简单举例,及应用
  20. jswebApi 03

热门文章

  1. 求 近代物理实验专业课排课 的算法
  2. 多通道主控的多CE NAND Flash 动态块模型
  3. 论文解读:DETR 《End-to-end object detection with transformers》,ECCV 2020
  4. 模拟快递100请求 通过快递单号获取物流信息
  5. Android解决分屏情况下背景拉伸问题
  6. linux file lock
  7. JavaScript之jQuery番外篇【打地鼠游戏的制作讲解】
  8. 图说Twitter简史 Twitter四周年回顾
  9. 企业生产发展从第一次工业革命到信息化时代
  10. iptables/netfilter