【Android杂谈】性能优化:渲染

栏目: IOS · Android · 发布时间: 5年前

内容简介:Google在Udacity上发布了《有关渲染最基本的概念是“刷新率”,指的是屏幕在一秒内的更新次数,以Hertz为单位。大部分Android设备的刷新率是60Hz,也就是说屏幕在一秒内更新60次,即每16.6667ms刷新一次屏幕。

Google在Udacity上发布了《 Android Performance 》的在线课程,介绍了如何通过 工具 识别和和修复性能问题。课程分为四节:渲染,计算,内存,耗电。比较系统,难度不高,学完大概6~8个小时。有些内容可能稍有过时(后文会提到官方推荐的新的工具及库),但整体还是非常推荐的。性能是软件最基本的需求之一,每个开发人员都应该学一定的性能优化知识。

刷新率&丢帧

有关渲染最基本的概念是“刷新率”,指的是屏幕在一秒内的更新次数,以Hertz为单位。大部分Android设备的刷新率是60Hz,也就是说屏幕在一秒内更新60次,即每16.6667ms刷新一次屏幕。

【Android杂谈】性能优化:渲染

如果程序没有在16ms内完成刷新屏幕的逻辑操作,比如下图中UI线程上的操作花费了24ms,就会出现丢帧:即用户在32ms内看到同样的画面。

【Android杂谈】性能优化:渲染

如果用户这时正在和UI交互,比如滑动窗口或者输入数据,就会有很明显的卡顿感,很容易抱怨App非常“卡”。

CPU & GPU

Android的渲染分为CPU和GPU两部分工作。其中CPU主要负责视图的测量,清除,重建和计算。CPU会通过计算将需要绘制的图形(文字、按钮等)转换成多边形或者纹理,之后通过调用Open GL接口,通过GPU进行栅格化的工作。栅格化是指计算屏幕上的像素点并进行绘制,是一个非常耗时的工作。而从CPU到GPU的数据传输也很耗时。而Android从Honeycomb版本开始对CPU和GPU之间的数据转换和传输做了很多优化,比如很多资源都会预先被打包到GPU之中,避免了绘制时的转换。

【Android杂谈】性能优化:渲染

Overdraw

虽然Android系统本身在渲染方面做了很多优化,但实际开发中还是会有渲染的性能问题,比如最容易出现的:过度渲染/过度绘制(Overdraw)。

过度绘制描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层级的试图结构中,如果不可见的UI也在做绘制的操作,会导致某些像素区域被绘制了多次,这样就会浪费大量的CPU和GPU资源。

【Android杂谈】性能优化:渲染

检测Overdraw最简单的办法是通过设置里面Show GPU Overdraw功能:Settings->Developer Options->Hardware accelerated rendering->Debug GPU overdraw->选择show overdraw areas。

【Android杂谈】性能优化:渲染

颜色的意义:

  • 原色表示没有Overdraw
  • 蓝色:一次Overdraw
  • 绿色:两次Overdraw
  • 粉色:三次Overdraw
  • 红色:四次或者更多的Overdraw

避免Overdraw的方法:

  • 移除布局中不必要的背景:一个不必要的背景可能是永远不可见的。
  • 使用 Canvas#clipRect() 来帮助系统识别自定义控件的可见区域,可见区域以外的区域在绘制时会被忽视。
  • 使用 Canvas#quickReject() 判断视图是否和某个矩形相交,从而跳过那些非矩形区域内的绘制操作。

View Hierarcy

除了Overdraw之外,另一个影响渲染性能的问题是视图层级。Android通过DisplayList把XML布局文件转换成GPU可以识别并绘制的对象。DisplayList在某个View第一次需要被渲染时,并通过GPU的绘制指令来进行渲染。如果View的属性发生了改变(例如移动位置),只需要执行DisplayList中的指令就可以完成View的更新。而如果View中的某些组件的内容被修改了,那么之前的DisplayList就无法继续使用了,系统需要重新创建一个DisplayList并重新执行渲染指令更新到屏幕上。

系统在绘制布局时需要进行:

  • 测量(Measurement):测量布局自身以及内部所有子控件
  • 摆放(Positiong):布局测量完成之后,根布局会将他们摆放到合适的位置。

当View的某个属性发生了变化,View自身会调用View#invalidate()方法,自底向上传播该请求,直到根布局。这个流程的表现性能取决于View的复杂程度。举个例子,假设某个Button的尺寸需要放大到两倍,需要通过父View重新测量并摆放其他子View的位置,只是修改一个Button的尺寸,会触发整个HierarcyView的重新测量和摆放。如果布局很复杂,很容易会出现性能问题。

【Android杂谈】性能优化:渲染

课程中介绍了通过 Hierarchy Viewer 来显示布局的层次关系,视图组件的各种属性。

【Android杂谈】性能优化:渲染

但其实 Hierarchy Viewer 在Android Studio 3.1之后已被标为deprecated,官方推荐 Layout Inspector 调试视图的层级和性能。

【Android杂谈】性能优化:渲染

提升布局性能:

  • 核心是尽量保持布局层级的扁平化,避免出现重复的嵌套布局。
  • 比如一些情况下(如课程示例), RelativeLayout 相较与 LinearLayout 更容易减少视图层级。
  • 16年GoogleIO介绍了 ConstraintLayout (课程没有介绍),对改善布局性能也有很大帮助。 

引用

https://cn.udacity.com/course/android-performance--ud825

https://developer.android.google.cn/studio/profile/inspect-gpu-rendering#profile_rendering

https://developer.android.google.cn/studio/profile/hierarchy-viewer

https://developer.android.google.cn/studio/debug/layout-inspector

https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout

(转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经允许请勿用于商业用途)


以上所述就是小编给大家介绍的《【Android杂谈】性能优化:渲染》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective Modern C++ 简体中文版

Effective Modern C++ 简体中文版

Scott Meyers / 高博 / 中国电力出版社 / 2018-4-23 / 99

想要彻底理解C++11和C++14,不可止步于熟悉它们引入的语言特性(例如,auto型别推导、移动语义、lambda表达式以及并发支持)。挑战在于高效地运用这些特性——从而使你的软件具备正确性、高效率、可维护性和可移植性。这正是这本实用的图书意欲达成的定位。它描述的正是使用C++11和C++14——现代C++来撰写真正卓越的软件之道。 涵盖以下主题: 大括号初始化、noexcept规格......一起来看看 《Effective Modern C++ 简体中文版》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具