找出Android卡顿的元凶——渲染性能优化( 四 )


  • 黄色
通常较短,它代表着 CPU 通知 GPU 你已经完成视图渲染了,不过在这里 CPU 会等待 GPU 的回话,当 GPU 说「好的知道了」,才算完事儿 。
假如橙色部分很高的话,说明当前 GPU 过于忙碌,有很多命令需要去处理,比如 Android 淘宝客户端,红色黄色通常会很高 。
  • 蓝色
假如想通过玄学曲线来判断流畅度的话,其实蓝色的参考意义是较大的 。蓝色代表了视图绘制所花费的时间,表示视图在界面发生变化(更新)的用时情况 。
当它越短时,即便是体验上更接近「丝滑」,当他越长时,说明当前视图较复杂或者无效需要重绘,即我们通常说的「卡了」 。
理解了玄学曲线不同颜色代表的意义,看懂玄学曲线就不难了 。一般情况下,当蓝色低于绿线时都不会出现卡顿,但是想要追求真正的丝般顺滑那当然还是三色全部处于绿线以下最为理想 。
Hierarchy ViewerHierarchy Viewer 是 Android Device Monitor 中的一个工具,它可以帮助我们检测布局层次结构中每个视图的布局速度 。
它的界面如下:
找出Android卡顿的元凶——渲染性能优化

文章插图
 
Hierarchy Viewer
有一定开发经验的小伙伴应该使用过它,不过现在已经被「弃用了」,google 推荐我们使用 Layout Inspector 来检查应用程序的视图层次结构 。
Layout Inspector
Layout Inspector 集成在 Android Studio 中,点击 Tools > Layout Inspector,在出现的Choose Process 对话框中,选择您想要检查的应用进程,然后点击 OK 。
找出Android卡顿的元凶——渲染性能优化

文章插图
 
Layout Inspector默认情况下,Choose Process 对话框仅会为 Android Studio 中当前打开的项目列出进程,并且该项目必须在设备上运行 。
如果您想要检查设备上的其他应用,请点击 Show all processes 。如果您正在使用已取得 root 权限的设备或者没有安装 Google Play 商店的模拟器,那么您会看到所有正在运行的应用 。否则,您只能看到可以调试的运行中应用 。
布局检查器会捕获快照,将它保存为 .li 文件并打开 。如图下图所示,布局检查器将显示以下内容:
找出Android卡顿的元凶——渲染性能优化

文章插图
 
Layout Inspector
优化布局使用上面的工具找到了过度重绘的地方,就需要优化自己的代码,我们可以通过下面几个方式进行优化 。
include
include 标签常用于将布局中的公共部分提取出来供其他 layout 共用,以实现布局模块化 。
merge
merge 标签主要用于辅助 include 标签,在使用 include 后可能导致布局嵌套过多,多余的 layout 节点或导致解析变慢 。
例如:根布局是 Linearlayout,那么我们又 include 一个 LinerLayout 布局就没意义了,反而会减慢 UI 加载速度 。
ViewStub
ViewStub 标签最大的优点是当你需要时才会加载,使用它并不会影响UI初始化时的性能 。
例如:不常用的布局像进度条、显示错误消息等可以使用 ViewStub 标签,以减少内存使用量,加快渲染速度. 。
ViewStub 是一个不可见的,实际上是把宽高设置为 0 的 View 。效果有点类似普通的 view.setVisible(),但性能体验提高不少 。
ConstraintLayout
约束布局 ConstraintLayout 是一个 ViewGroup,可以在 API 9 以上的 Android 系统使用它,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件 。从 Android Studio 2.3 起,官方的模板默认使用 ConstraintLayout 。
更多使用细节详见:Android 开发文档 - ConstraintLayout、ConstraintLayout,看完一篇真的就够了么? 。
优化自定义 ViewonDraw()
减少 onDraw() 耗时操作 。
clipRect() 与 quickReject()
我们可以通过 canvas.clipRect() 来帮助系统识别那些可见的区域 。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视 。
这个API可以很好的帮助那些有多组重叠组件的自定义 View 来控制显示的区域 。同时 clipRect 方法还可以帮助节约 CPU 与 GPU 资源,在 clipRect 区域之外的绘制指令都不会被执行,那些部分内容在矩形区域内的组件,仍然会得到绘制 。
找出Android卡顿的元凶——渲染性能优化

文章插图
 
clipRect
除了 clipRect 方法之外,我们还可以使用 canvas.quickReject() 来判断是否没和某个矩形相交,从而跳过那些非矩形区域内的绘制操作 。


推荐阅读