Android硬件加速

Android  2020年9月26日 am9:05发布4年前 (2020)更新 91es.com站长
90 0 0

前言

Android从3.0版本开始加入了硬件加速,这样就能够充分利用手机硬件GPU来提升界面的渲染效果。但是这种技术还有一些限制,比如有些开启了硬件加速的界面上无法使用Canvas的clipPath接口,一点调用就会抛出不支持的异常。现在来对硬件加速的小知识点做一些总结。

硬件加速

简单理解就是通过底层软件代码,将CPU不擅长的图形计算转换成GPU专用指令,由GPU完成。

Android3.0开始支持硬件加速,Android4.0默认启用硬件加速。

CPU和GPU

CPU : Central Processing Unit , 中央处理器,是计算机设备核心器件,用于执行程序代码。

GPU : Graphic Processing Unit , 图形处理器,主要用于处理图形运算,通常所说“显卡”的核心部件就是GPU。

硬件加速和软件加速

Android应用层的绘制主要有两种:软件绘制与硬件绘制。

软件绘制

CPU主导绘制,更新UI会重绘与脏区域相交的区域。

硬件加速

GPU主导绘制,提高显示刷新速度、更新UI只重绘脏区域,但是内存和电量消耗会比软件绘制大。

对应图形库

Skia : CPU 绘制 2D 图形; Open GL : GPU 绘制 2D / 3D 图形;

之后Android Q开始会使用 vulkan 来作为默认的图形库,有兴趣的可以提前了解下,这里不多赘述。

控制硬件加速(Controlling Hardware Acceleration)

如果您的应用程序仅使用标准视图和Drawables,则全局打开它不应导致任何不利的绘图效果。但是,由于所有2D绘图操作都不支持硬件加速,因此打开它可能会影响某些自定义视图或绘图调用。问题通常表现为不可见的元素,异常或错误渲染的像素。为解决此问题,Android为您提供了在多个级别启用或禁用硬件加速的选项。

android提供了以下四个级别的硬件加速控制:
  1. Application
  2. Activity
  3. Window
  4. View
Application级别

在应用的Android清单文件中,把下列属性添加到<application>元素中,能够开启整个应用程序的硬件加速:

<application android:hardwareAccelerated="true" ...>
Activity级别

如果不能再应用程序级别全局打开硬件加速,那么也可以在Activity级别上进行控制。在<activity>元素中使用android:hardwareAccelerated属性,能够启用或禁止Activity级别的硬件加速。以下示例启用全局的硬件加速,但却禁止了一个Activity的硬件加速:

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>
Window级别

如果需要更精细的控制,就可以使用下列代码来针对给定的Window来启用硬件加速:

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
View级别

在运行时,可以针对一个独立的View对象使用下列代码来禁止硬件加速:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

注意:目前不能在View级别开启硬件加速。View Layer除了禁止硬件加速以外,还有其他的功能,更多的相关信息请看下文的View layer。

判断一个View对象是否被硬件加速

有些时候,知道当前的View对象(尤其是自定义View)是否被硬件加速对应用程序来说是非常有用的。如果应用程序做了很多定制的绘图操作,并且不是所有的操作都会被新的渲染管道所支持,那么这种判断就特别有用。 有两种不同的方法来检查应用程序是否被硬件加速了:

View.isHardwareAccelerated()

如果View对象被绑定在硬件加速的Window,则返回true

Canvas.isHardwareAccelerated()

Canvas对象被硬件加速,则返回true 如果有必要在绘制代码中做这种检查,那么在可能的情况下,要使用Canvas.isHardwareAccelerated()方法来代替View.isHardwareAccelerated()方法。这是由于,当一个View对象跟一个被硬件加速的窗口绑定的时候,它依然能够使用使用一个非硬件加速的Canvas对象。例如,把一个View对象绘制到缓存中的一个位图时就会发生这种情况。

硬件加速使用建议

选择硬件加速来渲染2D图形可以有效改善性能,但是为了更有效的使用GPU,应该按照以下建议设计应用程序:

减少应用程序中View对象的数量

系统绘制越多的View对象,就会越慢。这种情况也适用于软件渲染管道。减少View对象数目是优化UI性能最有效的方式之一。

避免过度绘图

在彼此的顶部不要绘制太多的层。 移除那些完全被别的不透明View遮盖的View。 对于当前硬件的一个好的原则是,每帧的像素数不要大于屏幕上像素数的2.5倍(以位图的透明点阵数来计算)。

不要在绘图方法中创建渲染对象

一个常见的错误是每次调用渲染方法时创建一个新的Paint对象或Path对象。这样就会频繁地触发垃圾回收,导致硬件管道中的缓存和优化失效。

不要经常的编辑形状

对于复杂的形状,如路径和圆,是使用纹理掩码来呈现的。每次创建或修改路径,硬件通道都要创建一个新的纹理遮罩,这样会消耗大量的资源。

不要经常的编辑位图

每次改变位图内容,它都会被再次上传到GPU的纹理,以供下次绘制。

要小心的使用alpha相关的方法

当使用setAlpha()、 AlphaAnimation或ObjectAnimator,让一个View对象半透明时,需要双倍填充率来渲染到离屏缓存。当在一个大的View对象上应用透明效果时,要考虑把View对象的层类型设置为LAYER_TYPE_HARDWARE。

参考文章

  1. Android9.0 硬件加速(一)-开篇
  2. Android 硬件加速》、
  3. Android文档-硬件加速

 历史上的今天

  1. 2024: Lambda编程简介(0条评论)
  2. 2021: 洛夫:众荷喧哗(0条评论)
  3. 2021: 舒婷:北戴河之滨(0条评论)
  4. 2019: 林清玄:再加两个苹果(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

樊小纯:借我

借我一个暮年借我碎片借我瞻前与顾后借我执拗如少年借我后天长成的先天借我变如不曾改变借我素淡的世故和明白的愚借我可预知的脸借我悲怆的磊落借我温软的鲁莽和玩笑的庄严借我最初与最终的不敢借我不言而喻的不见借我一场秋啊可你说这已是冬天

gradlew编译的apk没有签名

前言window环境(gradlew.bat目录下)gradlew.bat app:assembleRelease//或./gradlew.bat app:assembleReleaseapp是module名,别搞错了哈Linux环境(gradlew目录下)./gradlew ap...

[摘]Android ANR日志分析指南

当你的项目越做越复杂,或者你的用户达到某个数量级的时候,你的代码不小心出现细小的问题,你会收到各种各样的bug,其中ANR的问题你一定不会陌生。本文将详细讲解ANR的类型、出现的原因、ANR案例详细分析、经典的案例。定义ANR(Application Not Responding) 应用程序无...

MediaMetadataRetriever解析媒体文件元数据

前言记录一下,一般获取视频、音频等媒体文件的元数据信息是使用MediaMetadataRetriever这个类。正文直接上代码。MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();//设...

刘亮程:最后一只猫

我们家的最后一只猫也是纯黑的,样子和以前几只没啥区别,只是更懒,懒得捉老鼠不说,还偷吃饭菜馍馍。一家人都讨厌它。小时候它最爱跳到人怀里让人抚摸,小妹燕子整天抱着它玩。它是小妹无数的几件玩具中的一个,摆家家时当玩具一样将它摆放在一个地方,它便一动不动,眼睛跟着小妹转来转去,直到它被摆放到另一个地方,还...

史铁生:爱情是孤独的证明

我知道一位现代女性,她说只要她的丈夫是爱她的,她丈夫的性对象完全可以不限于她,她说她能理解,她说她自己并不喜欢这样但是她能理解她的丈夫,她说:“只要他爱我,只要他仍然是爱我的,只要他对别人不是爱,他只爱我。”可是,当那男人真的有了另外的性对象而且这样的事情慢慢多起来时,这位现代女性还是陷入了痛苦。...