1.概述

  UI渲染操作通常依赖于两个核心组件:CPU与GPU。CPU负责包括Measure,Layout,Record,Execute的计算操作,GPU负责Rasterization(栅格化)操作。   所谓栅格化,就是将那些UI控件(如Button,Bitmap)拆分到不同的像素上进行显示。这是一个很费时的操作,GPU能够加快栅格化的操作。   为了能够使得App流畅,在Android中我们有一个16ms准则。这是因为Android平台的屏幕刷新频率一般为60Hz,也就是大概16.6ms一帧。也就是说在16ms内我们的CPU和GPU必须完成所有的计算,绘制,渲染操作,否则就有可能出现掉帧,卡顿现象,引发性能问题,伤害用户体验。   过度绘制(Overdraw)指的是屏幕上的某个像素在同一帧(16ms)的时间内被绘制了过多次数。   有很多原因可以导致丢帧,也许是因为你的layout太过复杂,无法在16ms内完成测量和布局,有可能是因为你的UI上有层叠太多的绘制单元,还有可能是因为动画执行的次数过多。也有可能是是主线程中做了其他耗时操作,或者线程数量太多。这些都会导致CPU或者GPU负载过重。

2.GPU过渡绘制调试

开启:adb shell setprop debug.hwui.overdraw show

关闭:adb shell setprop debug.hwui.overdraw false

3.过度绘制的分级:

原色:没有过度绘制

蓝色:1 次过度绘制

绿色:2 次过度绘制

粉色:3 次过度绘制(不应超过屏幕的四分之一)

红色:4 次及以上过度绘制(不能出现)

4.避免过度绘制

4.1去掉Activity的冗余的背景

(1)当我们新建一个Activity时,Activity的Theme主题上往往自动有一个背景。但是很多时候这个背景是多余的,我们自己使用的控件往往已经设置了背景;

在APP Theme中把背景改掉:

<style name="AppTheme" parent="android:Theme.Light.NoTitleBar"><item name="android:windowBackground">@null</item>...
</style>
复制代码

(2)还有很多时候我们在Activity的布局文件中的根Layout上就已经设置了background属性,这样的情况下,这个Activity自带的背景就多余了。

在Activity的onCreate()中试用以下代码:

getWindow().setBackgroundDrawable(null);
复制代码

如果是在Fragment中,就是

getActivity().getWindow().setBackgroundDrawable(null)
复制代码

4.2 ImageView的background和setImageDrawable()重叠

  我们平时使用ImageView等类似的显示图片的控件时,通常会有一个加载未完成时的占位图,很多时候我们习惯用background属性进行添加。等到网络将图片请求到之后我们又使用setImageDrawable()设置了图片,这样子图片会覆盖掉原来的占位图,但是Android系统绘制界面时原来的占位图和现在的图片都会被绘制,造成了Overdraw。

就是占位图和后来加载到的图片都使用setImageDrawable()来设置,而不要使用background

4.3 减少Drawable的复杂Shape

  使用复杂的Shape有时候也是引起过度绘制的一个因素,比如Stroke,虽然只是描边,但是会增加整个区域的一层过度绘制。例如,将下面的配置作为ImageView的背景。

<solid android:color="#FFF8F8F8" /><strokeandroid:dashGap="4dp"android:dashWidth="2dp"android:width="2dp"android:color="#ff1111" /><paddingandroid:bottom="10dp"android:left="10dp"android:right="10dp"android:top="10dp" /><corners android:radius="6dp" />
复制代码

在有stroke属性的时候,显示为淡红色,去掉stroke属性后,显示为绿色。

4.4使视图层级扁平化

  现代布局使视图堆叠和分层更加容易。然而,这样做却会过度绘制,从而导致性能降低。特别在每一个堆叠视图对象是不透明的场景中,可见和不可见的像素都需要绘制在屏幕上。

  如果遇到这类问题,可以通过优化视图层次结构来减少重叠的UI对象数量,从而提升性能。

要想扁平化布局效果,可以使用约束性布局ConstraintLayout。

4.5自定义控件中onDraw函数的正确使用

  在自定义控件中,我们经常会通过onDraw函数绘制一些复杂的形状、文字、图片等。但是这些Canvas的绘制函数,每一次调用就会增加一层的绘制,次数越多也就会导致越多的过度绘制。如我们用如下代码来自定义绘制图形,就会存在绘制三次的情况:

protected void onDraw(Canvas canvas) {// TODO Auto-generated method stubint width = getWidth();int height = getHeight();Paint paint = new Paint();paint.setColor(0xFFFFFFFF);canvas.drawColor(0xFFFFFFFF);canvas.drawRect(20, 20, width - 20, height - 20, paint);canvas.drawCircle(width / 2, height / 2, 50, paint);}
复制代码

4.6通过Merge标签减少View树层次

  我们在自定义可重用布局的时候,都会新建一个文件来存放这个布局。当我们在文件中include这个布局文件的时候,很可能就额外多了一层的布局。如果这时候使用Merge的话,再使用包含这个的布局的时候,系统会自动忽略merge层级,把它的子view直接放置与include平级的布局下。还有一种情况,例如在LinearLayout等布局里面嵌入一个布局时,刚好这个布局的根节点也是LinearLayout等布局的时候,既两层布局使用了同一种类型的布局时,这样就多了一层没有用的嵌套,而这个时候如果使用merge根标签就可以避免这样的问题,减少这层无用的嵌套。

  不过只能作为XML布局的根标签使用。当Inflate以开头的布局文件时,必须指定一个父ViewGroup,并且必须设定attachToRoot为true。

4.7通过ViewStub标签优化布局

  一些显示错误的界面、加载提示框的界面,ProgressBar等界面,以及用户很少会触发的界面,当这些不是必须显示的布局都堆在一起时,会对infalte性能、内存等产生不利影响。这个时候用ViewStub标签就很合适,可以将这些不常用的布局另外保存为布局文件,对应的位置布局用ViewStub标签代替。等到真正需要显示的时候再对ViewStub初始化。因为ViewStub是一个轻量级的View,它是一个不可见,且不占布局位置,占用资源非常小的控件。所以使用ViewStub后,可以加快Inflate的时间,减少创建的对象数量,从而提升性能和减少内存的占用。不过ViewStub只能Inflate一次,一旦初始化后该标签就会被真正的布局所代替。

4.8减少不需要的View

  一方面减少层级本身就是减少了view的数量,另外像一些场景,文字有大有小,有不同颜色,其实用一个TextView就可以实现,例如可以借助Spannable对象实现。不需要使用很多个TextView来实现。

另外,有时我们发现一个空白区域的占位也使用了一个view去做,其实用layout_margin属性或者用其他方式就能代替掉这个View。

android 过度绘制相关推荐

  1. Android过度绘制自动化

    Android 过度绘制指的是在屏幕某个像素在同一帧的时间内被绘制多次(超过一次),严重的过度绘制会浪费cpu及gpu资源导致性能问题.Google编辑精选对App页面的过度绘制有要求,因此需要对所有 ...

  2. Android 过度绘制优化

    Android 从一诞生到现在已经发布的 7.0 版本,卡顿和不流畅问题却一直被人们所诟病.客观地来讲,Android 的流畅性确实一直不给力,哪怕是某些大厂的 App ,也都不同程度地存在卡顿问题. ...

  3. Android之GPU过度绘制与图形渲染优化

    原址 前言 本文主要对过度绘制和图形渲染做一个概念性的描述. 同时以案例方式列出一些简单适用的优化措施. 如果你已对过度绘制有过一些了解,那么你应该明白,仅是简单的层级优化对过度绘制的改善是很小的.所 ...

  4. 【Android 性能优化】布局渲染优化 ( GPU 过度绘制优化总结 | CPU 渲染过程 | Layout Inspector 工具 | View Tree 分析 | 布局组件层级分析 )

    文章目录 一. GPU 过度绘制优化总结 二. CPU 渲染过程 三. CPU 渲染性能调试工具 Layout Inspector 四. Layout Inspector 组件树 DecorView ...

  5. 【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | Android 系统的渲染优化 | 自定义布局渲染优化 )

    文章目录 一. 背景设置产生的过度绘制 二. Android 系统的渲染优化 1. 透明组件数据传递 2. GPU 存储机制 3. Android 7.0 之后的优化机制 三. 自定义布局渲染优化 一 ...

  6. 【Android 性能优化】布局渲染优化 ( 过渡绘制 | 自定义控件过渡绘制 | 布局文件层次深 | GPU 过渡绘制调试工具 | 背景过度绘制 )

    文章目录 一. 过度绘制 二. 过度绘制两种情况 ( 自定义控件 | 布局文件 ) 三. 过度绘制调试 1. 打开过渡绘制调试工具 2. 过渡绘制调试中不同颜色的含义 3. 过渡渲染示例 四. 背景过 ...

  7. Android应用性能优化之优化列表头像过度绘制[一]

    为什么80%的码农都做不了架构师?>>>    操作的是否顺畅.卡顿,决定着整体的流畅程度. 事实上android跟iphone的差别,个人觉得很大程度上决定于流畅程度,无论是动画, ...

  8. Android检查GPU呈现模式和过度绘制

    Android提供了一些工具可以用来帮助分析你的UI是否存在图形绘制问题,例如执行过多不需要的绘制工作,或执行长时间的GPU操作. 分析GPU呈现模式 GPU呈现模式工具以滚动直方图的形式展现,显示渲 ...

  9. Android开发者选项之GPU过度绘制

    做设计的人很少能知道GPU过度绘制是个什么鬼?跟设计有什么关系?今天就让大家了解了解,首先来普及一下Android开发者选项中的Debug GPU overdraw. GPU过度绘制定义 如果你粉刷过 ...

最新文章

  1. AI技术出海 - 阿里云GPU服务器助力旷视勇夺4项世界第一
  2. vue 分享微信传参_vue 中使用微信分享接口(简单实用)
  3. DataTable 数据去重复
  4. android 4.0之前版本号出现JSONException异常
  5. js中bind、call、apply函数的用法
  6. 如何提高电脑办公效能
  7. TaoLer V1.7.12版本简单迅捷的轻论坛系统源码
  8. 利用ettercap进行简单的基于数据库的ARP毒化攻击
  9. operator 模块详解
  10. ETL介绍与ETL工具比较
  11. android adb 刷机工具,ADB 工具 ADB 工具刷机-完美教程资讯
  12. Python3 爬虫(二) -- 伪装浏览器
  13. Android内存优化深入解析
  14. android中实现图片圆形效果
  15. Mac效率神器Alfred4以及常用Workflow【文末有福利】
  16. 非对称加密RSA文本和Excel文件加密练习
  17. 《RFID技术与应用》测试选择题
  18. limbo运行veket linux,Veket——『350M』的操作系统,五脏俱全全到可怕!
  19. umi中使用plugin-initial-state插件(initialState)
  20. canvas实现图片压缩和缩放

热门文章

  1. PLM和PDM相互关系
  2. 谷歌公布GSoC 2020 暑期代码项目名单,200个开源项目30个新增
  3. 郑宇、沈抖领衔共话 AI 业界应用挑战 | IJCAI 2019
  4. 基于PaddlePaddle的机器翻译教程 | 深度学习基础任务系列
  5. 机器学习之单变量线性回归
  6. 未来医疗AI发展的八大趋势
  7. 距离产生美?k近邻算法python实现
  8. 前沿丨DeepMind提出神经元删除法:通过理解每个神经元来理解深度学习
  9. 《用Python进行自然语言处理》第3章 加工原料文本
  10. 麦肯锡季刊 | 人工智能的发展与障碍