抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > 【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | An

【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | An

时间:2019-07-09 10:28:40

相关推荐

文章目录

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

一、 背景设置产生的过度绘制

1. 背景设置产生的过度绘制 :

① 组件背景 :每个组件每设置一次背景 , 该组件的区域就会增加一层绘制 , 如 LinearLayout 线性布局设置背景颜色 , TextView 设置背景颜色 , 都会增加该组件区域内的过渡绘制 ;

② 布局背景 :布局文件总的背景 , 会增加一次 GPU 绘制 ;

③ 主题背景 :Activity 界面的主题背景 , 会增加一次 GPU 绘制 ;

2. 组件背景设置策略 :不要随便为组件添加背景 , 添加一次背景 , 就增加一次 GPU 绘制 ;

不要随意给布局中的 UI 组件设置背景 , 能不设置背景的就不设置背景 , 如 ImageView 组件 , 设置一张图片 , 会增加一次绘制 , 如果再给该 ImageView 组件设置背景颜色 , 那么又会增加一次绘制 , 那么该 ImageView 组件肯定过渡绘制了 ;

二、 Android 系统的渲染优化

在 【Android 性能优化】布局渲染优化 ( CPU 与 GPU 架构分析 | 安卓布局显示流程 | 视觉与帧率分析 | 渲染超时卡顿分析 | 渲染过程与优化 ) 博客中分析了图像渲染的 16 毫秒过程中

CPU 渲染CPU 传递数据到 GPUGPU 渲染

是三大耗时操作 , 上述分析的背景过渡绘制 , 是从减少 GPU 渲染时间角度出发 , 降低图像渲染时间 ;

CPU 传递数据给 GPU 非常耗时 ;

下面分析是从 降低 CPU 传递数据到 GPU 时间 角度出发 , 进行的优化 , 这部分优化是由 Android 系统完成的 ;

1. 透明组件数据传递

Android 系统做了如下自动优化操作, 当组件的背景是透明的 , 那么 CPU 将该组件转为多维向量图片 ( 多边形和纹理组成 ) 时发现该组件是透明的 , 该组件的图像信息就不会传递给 GPU 进行渲染 , 从而减少了 CPU 向 GPU 传递的数据大小 ; 之前讲到过 , CPU 向 GPU 传递数据也是一个非常耗时的操作 , 因此该优化 , 也降低了组件渲染的时间 ;

透明组件摆放处理 :CPU 不传递这些组件到 GPU 中 , 但是在布局中仍然正常摆放 ;

2. GPU 存储机制

1. GPU 存储纹理机制 :GPU 中的显存可以存储纹理资源 , 即多维向量图形资源 , 在渲染时 , 可以直接使用该存储的资源 , 不用每次都让 CPU 传递数据过来 ;

2. CPU 传递主题资源给 GPU 机制 :传递主题资源是一次性传递 , 主题中的 背景 , 颜色 , 图片 ( Bitmap , Drawable ) 等资源都打包存储在了多维向量图形 ( 多边形 和 纹理 ) 中 , 传递给 GPU 进行渲染 , GPU 每次进行渲染时直接从存储区域取出这些资源 , 进行渲染 , 不再依赖 CPU 实时传递 ;

这种变化较少的资源 , 适合一次性加载 , 应用或界面的主题资源基本不会改变 ;

3. 普通的 UI 组件资源 :如果是普通的 UI 组件 , 那么就不能只加载一次了 , 需要每次渲染时 , CPU 都要将组件加载到内存 , 并转成的多维向量图形 , 最后传递给 GPU ;

3. Android 7.0 之后的优化机制

Android 7.0 之后的优化机制 :

① 7.0 系统优化前 :Android 7.0 之前调用 UI 组件的 invalidate 方法 , 组件会回调 onLayout , onMeasure 和 onDraw 方法 ;

② 7.0 系统优化后 :Android 7.0 之后调用 UI 组件的 invalidate 方法 , 组件不会回调 onLayout 和 onMeasure 方法 , 只会调用 onDraw 方法 ;

③ 7.0 系统优化后工作机制 :在 GPU 中缓存 UI 组件对应的多维向量图形 ( 纹理 ) , 当该组件位置或颜色等外观发生变化时 , 就会通知 CPU , 重新进行加载 , 如 onLayout 摆放 , onMeasure 测量 , 并转为多维向量图 ( 纹理 ) , 传递给 GPU 进行渲染 ; 如果没有发生变化 , 调用 invalidate 方法 , 只会在 GPU 中重新渲染 ; 不会重新 摆放 ( onLayout ) 与 测量 ( onMeasure ) ;

三、 自定义布局渲染优化

1. 自定义组件过度绘制问题描述 :自定义控件 , 在自定义的 onDraw 方法中 , 绘制多张图片 , 如果图片之间产生重叠 , 重叠绘制的部分就出现了过度绘制 ;

2. 自定义组件绘制原则 :

① 两张图片 :图片 AAA 和 图片 BBB ;

② 图片覆盖 :当图片 AAA 被图片 BBB 覆盖时 , 只绘制图片 AAA 显示的部分区域 , 图片 AAA 被图片 BBB 覆盖的部分不再绘制 ;

③ 图片 AAA 只绘制没有被覆盖的部分 :只在图片 AAA 显示的区域绘制图片 AAA 的区域 , 如下图黄色框中的区域 ;

3. 实现上述图片 AAA 在 Canvas 画布上绘制部分图片方式 :

① 完整画布 :onDraw 函数中的 Canvas canvas 参数是完整的画布 ;

② 取出图片 AAA 绘制部分的 Canvas 画布 :这部分画布就是上图中 , 被黄色框框起来的画布 , 传入的四个参数是黄色矩形框的左上右下参数 , 注意剪切之前先保存画布 ;

// 剪切画布前 , 先保存画布 , 之后还要恢复回去canvas.save();// 剪切画布canvas.clipRect(left, top, right, bottom);

③ 在剪切后的画布中绘制图片 AAA :在剪切后的画布中 , 绘制图片 AAA , 注意绘制完成后 , 恢复画布 ;

// 在剪切后的画布中 , 绘制图片 Acanvas.drawBitmap(...);// 绘制完毕后 , 恢复画布canvas.restore();

④ 绘制效果 :上述代码的绘制效果大概就是绘制了部分图片 AAA , 下图中的下面的部分图片 AAA 展示 ;

3. clipRect 函数原型 :剪切画布 , 获取 Canvas 完整画布的子画布 , 传入左 , 上 , 右 , 下 , 四个值 , 将画布剪切出来 ;

public boolean clipRect(float left, float top, float right, float bottom) {return nClipRect(mNativeCanvasWrapper, left, top, right, bottom,Region.Op.INTERSECT.nativeInt);}

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

如果觉得《【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | An》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。