当前位置: 首页 > article >正文

Android性能优化系列——卡顿优化

卡顿,就是用户体感界面不流畅。我们知道手机的屏幕画面是按照一定频率来刷新的,理论上讲,24 帧的画面更新就能让人眼感觉是连贯的。但是实际上,这个只是针对普通的视频而言。对于一些强交互或者较为敏感的场景来说,比如游戏,起码需要 60 帧,30 帧的游戏会让人感觉不适;如果实现不卡顿,则需要在 16ms 内做完所有的操作才不会造成卡顿。

卡顿一般可能由以下条件造成的:

  1. UI卡顿
  2. 内存泄漏,内存抖动,内存溢出
  3. IO阻塞,IO操作,网络操作
  4. 图片,数据处理不当等等
1.UI优化

Android中通常把布局文件写在XML中,Android需要把XML布局文件转换成GPU能够识别并绘制的对象,CPU负责把UI组件计算成Polygons,Texture纹理,然后交给GPU进行栅格化渲染,最后硬件将信息绘制到屏幕上。

为了使APP流畅,我们需要在每一帧16ms内完成所有的CPU与GPU的计算、绘制、渲染等操作,也就是帧率为60fps,为什么要帧率为60fps呢?因为人眼与大脑之间的协作无法感知超过60fps的画面更新,开发APP的性能目标就是保持60fps,这意味着每一帧只有16ms(1000/60)的时间来处理所有任务。

但是我们遇到很多帧率小于刷新频率,这种情况下,某些帧显示的画面内容就会与上一帧的相同,帧率如果从高于60fps突然掉落到低于60fps就会发生卡顿不顺滑的情况。这也是用户感受卡顿的原因所在。

我们一般都比较了解 view 渲染的三大流程,但是 view 的渲染远不止于此:

此处以一个通用的硬件加速流程来表征
  1. Vsync 调度:很多同学的一个认知误区在于认为 vsync 是每 16ms 都会有的,但是其实 vsync 是需要调度的,没有调度就不会有回调;
  2. 消息调度:主要是 doframe 的消息调度,如果消息被阻塞,会直接造成卡顿;
  3. input 处理:触摸事件的处理;
  4. 动画处理:animator 动画执行和渲染;
  5. view 处理:主要是 view 相关的遍历和三大流程;
  6. measure、layout、draw:view 三大流程的执行;
  7. DisplayList 更新:view 硬件加速后的 draw op;
  8. OpenGL 指令转换:绘制指令转换为 OpenGL 指令;
  9. 指令 buffer 交换:OpenGL 的指令交换到 GPU 内部执行;
  10. GPU 处理:GPU 对数据的处理过程;
  11. layer 合成:surface buffer 合成屏幕显示 buffer 的流程;
  12. 光栅化:将矢量图转换为位图;
  13. Display:显示控制;
  14. buffer 切换:切换屏幕显示的帧 buffer;

所以UI渲染机制中的任何流转过程发生异常,均会造成卡顿

在View第一次被渲染时,DisplayList就会被构建,View显示到屏幕上时,会执行GPU的指令来进行渲染,如果后续还有移动位置等操作时再次渲染这个View时,仅仅额外执行一次渲染指令就可以了。但是如果修改了View中某些可见组件,DisplayList就无法再次使用,需要重新构建再渲染。任何View中的绘制内容发生变化时,都会执行DisplayList构建和渲染,更新到屏幕等一系列操作,这个流程表现的性能取决于View的复杂程度,View的状态变化以及View渲染管道的执行力。所以我们需要尽量减少过渡绘制(OverDraw)。

综上,针对页面布局的性能,层级,测量绘制时间进行优化,所以布局优化就是减少层级,减少OverDraw,性能耗费少,越简单越好。

而我们平时敲的代码主要就涉及上面的3,4,5,6,我们可以在上面的代码进行优化,优化的方向可以看我另一篇文章:

Android性能优化系列——UI优化-CSDN博客

2.内存优化

下面是内存泄漏的常见原因和解决方案,具体可以去看以下文章

Android性能优化系列——内存优化-CSDN博客

 


http://www.kler.cn/a/534548.html

相关文章:

  • beyond the ‘PHYSICAL‘ memory limit.问题处理
  • InnoDB和MyISAM的比较、水平切分和垂直切分、主从复制中涉及的三个线程、主从同步的延迟产生和解决
  • 【初阶数据结构和算法】八大排序算法之插入排序(直接插入排序、希尔排序及其对比)
  • C语言:深入了解指针3
  • Vue.js 如何选择合适的组件库
  • python算法和数据结构刷题[3]:哈希表、滑动窗口、双指针、回溯算法、贪心算法
  • 【C++】指针的基础概念与应用解析
  • tkvue 入门,像写html一样写tkinter
  • uniapp小程序自定义中间凸起样式底部tabbar
  • 记录使用libvirt创建虚拟机、自定义qcow2镜像
  • 图像分割中根据mask的ROI,去除mask和image中没有勾画ROI层数以外的图像
  • 数据库技术基础
  • Certum OV企业型通配符SSL
  • 常用工具类——Collections集合框架
  • c++ 基础 计算机的内存和寻址机制
  • Redis面试题总结(题目来源JavaGuide)
  • LeetCode 3442.奇偶频次间的最大差值 I
  • ASP.NET Core筛选器Filter
  • Vue3.5常用特性整理
  • 一、tsp学习笔记——开发环境搭建
  • 计算机网络笔记再战——理解几个经典的协议6——TCP与UDP
  • Mysql-增删改查(知识点总结)
  • WPS的word文档加密
  • module ‘matplotlib.cm‘ has no attribute ‘get_cmap‘
  • 在https下引用IC卡读卡器web插件
  • LeetCode 257.二叉树的所有路径