最近项目中遇到了因为硬件加速引起的一些问题,故这里深入学习了解一下关于硬件加速的一些东西

背景

什么是硬件加速?

硬件加速是Android系统在绘制图形时采取的一种方式。

图形的绘制,本质上就是界面的渲染。在渲染界面的时候,是要经过一系列计算的,这部分计算通常是逻辑较简单,但数据量庞大的浮点运算。

在操作系统层面,有一个东西叫中央处理器——CPU,他是计算机设备的核心器件之一,主要功能是解释计算机指令以及处理计算机软件中的数据。除此之外,计算机还有一个器件,叫做图形处理器——GPU,他类似于CPU,但是是专门为运行绘图运算的微处理器。

那么CPU和GPU的区别在哪里呢?

CPU内部算数逻辑单元(ALU)较少,控制器较复杂,适合进行复杂的逻辑运算

GPU控制器简单,但是包含了较多的算数逻辑单元,可并行运行大量计算

结果显而易见,因为界面渲染的计算是逻辑简单但是数据量很大的浮点运算,所以如果使用CPU来对界面渲染做运算,效果自然比不了GPU。

所以,硬件加速绘制图形是一般会采用的软件绘制就是由CPU来绘制的。硬件加速,就是通过底层代码,将CPU中一部分不擅长的图形计算转换成GPU专用指令,然后交给GPU来完成。而对于Android来讲,硬件加速就是将View的绘制工作从原来的CPU转交给GPU来做。

原理

硬件绘制之所以比软件绘制“快速”,除了如上所述的奖一部分计算量交给更适合的硬件来做外,还有一个很重要的原因在于绘制区域即绘制内容的选择不一样。

在关闭了硬件加速,即采用软件绘制时,绘制区域是这样获取的:从要执行 invalidate() 方法的View开始,遍历从跟View开始的整个View结构,标记出需要重新绘制的 脏区域。在这个过程中,除了我们直接修改的View需要绘制外,其他的所有View,都可能因为遮盖、相交等原因,被标记为需要绘制,这样一来绘制的区域就会变的很大。这样一来一旦开始绘制,搞不好会有很多“无辜”的View也被重新绘制,虽然这些View未必真的需要被重绘。

而采用硬件加速时,就完全不一样了。硬件绘制,首先将View抽象为 RenderNode 节点,将对View的绘制,抽象为 DrawOp ,每个View不仅持有自己的绘制操作 DrawOp 组成的List,还持有其子View的绘制入口,而 DrawOp 中保存有对应的 OpenGL 绘制命令,这样便形成了一个完整的树状结构。其次,硬件绘制是直接交给一个Render线程来执行绘制的,而不是主线程,这样也缓解了主线程的部分压力。最后,在进行实际绘制时,每个View的实际绘制操作对应于 DrawOp ,在绘制时只需更新其中保存的绘制命令,即可完成这个View单独的绘制,而不会影响到其他View。

问题

虽然硬件加速有很多优点,但是也有许多坑。

首先,一些Api方法是不支持硬件加速的。其次,在使用Webview时,如果启用了硬件加速,那么有时会出现花屏、闪烁等异常状况。

最后,正如前面说的,由于不支持一些Api,所以在做自定义View时,有可能因为开启硬件加速导致View的绘制效果不理想。

如何使用

一开始Android是默认关闭硬件加速的。从Android4.0版本开始,默认是开启了硬件加速的。硬件加速固然有很多优点,但是由于种种原因(系统设计、历史遗留、以及自身的局限性)导致在有些情况会出现一些问题,这个时候又需要我们手动关闭了。

硬件加速的开关分为四个级别,分别为App级别、Activity级别、Window级别以及View级别。

App级别:直接在 AndroidManifest.xml 文件中, 标签下加入一个属性,属性值为 true 为开启, false 为关闭:

Activity级别:类似于App级别,在 标签下加入同样的属性:

Window级别: 在Window级别,只能通过Java代码形式动态的开启硬件加速而不能关闭:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

View级别:View层比较特殊,这里只允许关闭硬件加速,而无法开启。而且相关的接口并不是专门用来做硬件加速开关的,而是在给View设置Layer时“顺便”关闭了硬件加速:

view.setLayerType(LAYER_TYPE_SOFTWARE, null);

这个方法只是给View设置了一个LayerType,而且参数有三种:LAYER_TYPE_SOFTWARE LAYER_TYPE_HARDWARE LAYER_TYPE_NONE,这是什么意思呢?关于这一部分,在官网中有详细的解释:

You currently cannot enable hardware acceleration at the view level. View layers have other functions besides disabling hardware acceleration. See View layers for more information about their uses.

官方说在View层只能关闭,不能开启,至于为什么,引用一段扔物线大佬的解释:

setLayerType() 这个方法,它的作用其实就是名字里的意思:设置 View Layer 的类型。所谓 View Layer,又称为离屏缓冲(Off-screen Buffer),它的作用是单独启用一块地方来绘制这个 View ,而不是使用软件绘制的 Bitmap 或者通过硬件加速的 GPU。这块「地方」可能是一块单独的 Bitmap,也可能是一块 OpenGL 的纹理(texture,OpenGL 的纹理可以简单理解为图像的意思),具体取决于硬件加速是否开启。采用什么来绘制 View 不是关键,关键在于当设置了 View Layer 的时候,它的绘制会被缓存下来,而且缓存的是最终的绘制结果,而不是像硬件加速那样只是把 GPU 的操作保存下来再交给 GPU 去计算。通过这样更进一步的缓存方式,View 的重绘效率进一步提高了:只要绘制的内容没有变,那么不论是 CPU 绘制还是 GPU 绘制,它们都不用重新计算,而只要只用之前缓存的绘制结果就可以了。

所以,如果给View设置了Layer,且值为SOFTWARE,那么就是用软件来做View Layer,自然就关闭了硬件加速。而如果硬件加速已经关闭,参数HARDWARE的作用跟SOFTWARE一样,自然也无法开启硬件加速。而值为NONE时,直接就关闭了ViewLayer,所以在View层只能关闭、不能开启,正如官方文档所说:

LAYER_TYPE_NONE: The view is rendered normally and is not backed by an off-screen buffer. This is the default behavior.

LAYER_TYPE_HARDWARE: The view is rendered in hardware into a hardware texture if the application is hardware accelerated. If the application is not hardware accelerated, this layer type behaves the same as LAYER_TYPE_SOFTWARE.

LAYER_TYPE_SOFTWARE: The view is rendered in software into a bitmap.

安卓禁用硬件加速_Android硬件加速相关推荐

  1. 安卓禁用硬件加速_Android硬件加速详解

    从Android3.0(API Level 11)开始,支持硬件加速,可充分利用GPU的特性,使得界面渲染更加平滑. 但是硬件加速自身并非完美,在某些Webview版本上,比如Android5初期的一 ...

  2. 安卓禁用硬件加速_硬件加速  |  Android 开发者  |  Android Developers

    从 Android 3.0(API 级别 11)开始,Android 2D 渲染管道支持硬件加速,也就是说,在 如果您的目标 API 级别为 14 及更高级别,则硬件加速默认处于启用状态,但也可以明确 ...

  3. 怎么关闭计算机硬件加速,启用硬件加速是什么意思?如何关闭[详细说明]

    引言:我相信经常使用计算机的朋友必须熟悉"硬件加速"一词!但是,对于某些计算机新手,他们常常感到困惑.启用硬件加速是什么意思?启用它之后,我们的计算机会发生什么?有些人不知道在启用 ...

  4. java安卓布局与画布_Android 画布绘图

    我们已经介绍了Canvas,在那里,已经学习了如何创建自己的View.在第7章中也使用了Canvas来为MapView标注覆盖. 画布(Canvas)是图形编程中一个很普通的概念,通常由三个基本的绘图 ...

  5. 适女化科技(二):让女性更安全的两条技术路径:软件硬件化与硬件软件化...

    在本系列第一篇中,我们从生物性别和社会性别的角度,简要归纳了一些女性在马斯洛需求层次中的不同诉求. 按照该理论,高级需求出现之前,必须要先满足低级需求,既生理和安全需求.尽管生存需求被认为是低级需求, ...

  6. PHP快还是HTML快,PHP_HTML-加速、再加速,web开发人员是否必须掌握复杂 - phpStudy...

    HTML-加速.再加速 web开发人员是否必须掌握复杂的组件技术才能加快html页面的访问速度?答案是:不一定!实际上,有许多关于HTML与DHTML方面的技巧,它们原理简单而且上手容易.无论是技术高 ...

  7. 台式计算机由哪些硬件组成,台式电脑硬件是由哪些组成的 - 卡饭网

    台式电脑硬件的安装步骤 台式电脑硬件的安装步骤 当大家需要一台台式电脑时,大家肯定会想到DIY装机,不仅性价比高,而且可以恰好满足自己的需求,当然装机可以让电脑城的师傅帮你完成,但是为了提高大家的动手 ...

  8. 网站加速和服务器加速区别,cdn加速与不加速区别

    cdn加速与不加速区别是什么?使用cdn加速与不使用cdn加速的网站,在访问速度.数据安全.SEO优化和 1.网站访问速度差异 出于 使用CDN加速功能,不仅访问网站的速度提高了,跳出率减少了,也会利 ...

  9. (230)数据处理或加速方法(加速处理器)

    (230)数据处理或加速方法(加速处理器) 1 文章目录 1)文章目录 2)FPGA入门与提升课程介绍 3)FPGA简介 4)数据处理或加速方法(加速处理器) 5)技术交流 6)参考资料 2 FPGA ...

最新文章

  1. 小弟的新书《Ext JS权威指南》终于出版了
  2. listFiles()
  3. 八、TFTP服务器搭建及应用
  4. html图片postmultipart,sendmail-MIMEText-MIMEImage-MIMEMultipart.py——发送带图片的HTML格式报表...
  5. zend guard6的使用
  6. Java虚拟机详解----常用JVM配置参数
  7. 仓库处理中 无法修改_临沂用友U8erp系统软件如何新增仓库?
  8. 未来茅台酒会怎样跌下神坛?
  9. Vue 学习随笔四 - 路由介绍
  10. 适合入门的linux教程,Linux入门记录系列教程,适合Linux初学者阅读
  11. 测试结果可视化翻译_流行测验:此民意调查结果可视化有什么问题?
  12. fake_useragent导入无法引用的解决方法
  13. linux cat命令查找文件内容
  14. java间接调用_无法解析类型 java.util.Map$Entry。从必需的 .class 文件间接引用了它...
  15. 绿皮车里的温馨服务 情暖回家路
  16. php sleep usleep,php中sleep()和usleep()函数使用对比
  17. Velocity是什么?
  18. RT5350使用uboot从U盘启动linux成功
  19. PhpStorm设置等号对齐
  20. Huffman编码算法之Java实现

热门文章

  1. 学会java足够开发app吗_请问如何两个月内在不懂java 的情况下学会开发app?
  2. visio付款流程图_职场人士常用的3款超好用流程图软件!
  3. 微信账单怎么查?微信流水账单怎么打印
  4. 《Arduino与LabVIEW开发实战》第3章 如何连接Arduino与LabVIEW
  5. ZCMU暑期训练四-G - Alex and a Rhombus
  6. 如何写出好文案,不妨看看这篇(上)
  7. Retrofit2.0介绍使用封装
  8. 快消品图像识别丨无人店背后的商品识别技术
  9. widowns上从chrome上抓取图片
  10. 狂野飙车4java游戏音乐_狂野飙车8赛车背景音乐名称大全