美文网首页Android开发经验谈
Android 性能优化之 —— 渲染篇

Android 性能优化之 —— 渲染篇

作者: 码农的书柜 | 来源:发表于2020-12-31 15:47 被阅读0次

说到 Android 性能,不得不说一下光头哥 Colt McAnlis 这位大神,Colt McAnlis 是在 Google 主要从事 Android 中性能相关工作的,我每次很喜欢看他讲,幽默诙谐,对 Android 性能方面有很深入的研究,也是我敬仰的 Google 大神之一;

而今天我也做好了准备,我们就从性能优化 —— 渲染篇讲起。

应用性能优化的步骤

  • 获取信息
  • 分析数据
  • 采取行动

设计 vs 性能

现在众多开发 APP 的公司,为了让 App 达到很炫丽的视觉冲击效果,会需要在界面上层叠很多的视图组件,很多开发者在开发中注重的基本上都是达到这样的功能效果仅此而已,大多数可能都不会去关心性能是如何的? 只要 App 功能正常不出异常,那么这款 App 差不多就 OK 了,但是往往这样缺乏性能优化的 App 在用户的手上使用时,回出现各种卡顿、黑屏的情况,致使用户最终不得不卸载你的这款应用。

所以我们在开发一款应用的时候,不仅要实现它的功能,性能也不要忽视。

系统会每隔 16s 重新绘制一次 activity,1000ms/60hz=16.666ms/frame

如果在 1000/60=16.67ms 内没有办法把这一帧的任务执行完毕,就会发生丢帧的现象。丢帧越多,用户感受到的卡顿情况就越严重。

Android CPU 和 GPU

导致卡顿的第一个原因就是:渲染

渲染操作通常依赖于两个核心组件:CPUGPU

CPU 方面的因素:不必要的布局和失效 ,这些内容必须在视图层次结构中进行测量、清除并重新创建。一方面,重建显示列表的次数太多,另一方面花费太多的时间在作废视图层并进行不必要的重绘,使更新显示列表或者其他缓存资源时导致 cpu 工作过度,出现了卡顿。

GPU 方面的因素:像素着色过程中,通过其他工具进行后去着色时浪费里 GPU 处理时间。

Activity 的显示?

colt 说: 要想开发一款性能优越的应用,你必须了解底层是如何运行的。

Activity 是如何绘制到屏幕上的?复杂的 XML 布局文件和标记语言是如何转化成用户能看懂的图像的?

答案是:‘格栅化’操作

格栅化:将字符串、按钮、路径或者形状等拆分到不同的像素上在屏幕上进行显示。==> GPU 完成这一操作

GPU 使用一些指令的基础指令集,主要是多边形和纹理,也就是图片

CPU 在屏幕上绘制图像前,会向 GPU 输入这些指令,这一过程通常使用的 API 就是 Android 的 OpengGL ES

UI 对象 => CPU 转换为多边形或者纹理 ==> GPU 格栅化

在 Android 里面那些由主题所提供的资源,例如 Bitmaps,Drawables 都是一起打包到统一的 Texture 纹理当中,然后再传递到 GPU 里面,这意味着每次你需要使用这些资源的时候,都是直接从纹理里面进行获取渲染的。当然随着 UI 组件的越来越丰富,有了更多演变的形态。例如显示图片的时候,需要先经过 CPU 的计算加载到内存中,然后传递给 GPU 进行渲染。

文字的显示比较复杂,需要先经过 CPU 换算成纹理,然后交给 GPU 进行渲染,返回到 CPU 绘制单个字符的时候,再重新引用经过 GPU 渲染的内容。动画则存在一个更加复杂的操作流程。

为了能够使得 App 流畅,我们需要在每帧 16ms 以内处理完所有的 CPU 与 GPU 的计算,绘制,渲染等等操作。

渲染性能优化就是:尽可能地上传数据到 GPU,然后尽可能长的在不修改的条件下保存数据

GPU 性能问题瓶颈:过度绘制

过度绘制

定义:指的是屏幕上的某个像素点在同一帧的时间里被绘制多次

工具:开发者选项 => “Debug GPU overdraw” ==> show

(1x (这个像素点被绘制了 2 次) 是蓝色,然后还有 2x 3x 4x)

蓝色,淡绿,淡红,深红代表了 4 种不同程度的 Overdraw 情况,我们的目标就是尽量减少红色 Overdraw,看到更多的蓝色区域。

两种清除过度绘制的方法:

  • 要从视图中清除哪些不必要的背景和图片,它们不会在最终渲染的图像中显示
  • 对视图中重叠的屏幕区域进行定义,从而降低 CPU 和 GPU 的消耗

剪辑

剪辑:Android 设法避免绘制哪些最终界面中不显示的 UI 组件,你能确定某个对象会被完全阻挡,那就没必要去绘制它,这时候就需要剪辑

剪辑无法应对复杂的自定义 View (比如纸牌层叠), 这时候就需要使用 Canvas.clipRect (ClipRect API 帮助系统识别出无需绘制的区域)

DisplayList

定义: Android 需要把 XML 布局文件转换成 GPU 能够识别并绘制的对象。这个操作是在 DisplayList 的帮助下完成的,持有所有要交给 GPU 绘制到屏幕上的数据信息列表

请注意:任何时候 View 的绘制内容发生了变化,都需要重新执行 DisplayList,并重新执行指令更新到屏幕上,渲染 DisplayList,更新到屏幕上等一系列操作。这个流程的表现性能取决于你的 View 的复杂程度,View 的状态变化以及渲染管道的执行性能。

Hierarchy Viewer

打开步骤:Android Studio => Tools => Android => Android Devices Monitor

rebder_11

Hierarchy 的好用之处:它能帮助你从 Android 的角度去理解你的用户界面的结构,同时可以帮助你确定哪些视图是多余的

Venn 图形图标,绿黄红三种颜色的圆点表示了渲染速度的快慢,最左边的圆点代表渲染管道的测量阶段,中间的表示布局阶段,最右边的表示渲染管道的绘制阶段

层级扁平化

提升免出现重复的嵌套布局。

以上就是个人对《Android 性能优化之 —— 渲染篇》的主要内容进行的总结,后面有空继续总结下一篇性能优化的笔记

————本文已分类的核心技术点收录至我的【Github】,欢迎大家的Fock和Star。

相关文章

网友评论

    本文标题:Android 性能优化之 —— 渲染篇

    本文链接:https://www.haomeiwen.com/subject/dpzloktx.html