android硬件加速

Android 应用的开发过程中,我们经常会接触到“硬件加速”这个词。由于 操作系统 对底层软硬件封装非常完善,上层软件开发者往往对硬件加速的底层原理了解很少,也不清楚了解底层原理的意义,因此常会有一些误解,如硬件加速是不是通过特殊 算法 实现页面渲染加速,或是通过硬件提高CPU/GPU运算速率实现渲染加速?都不是的,其实硬件加速就是运用GPU优秀的运算能力来加快渲染的速度,而通常的基于软件的绘制渲染模式是完全利用CPU来完成渲染。
本文尝试从底层硬件原理,一直到上层代码实现,对硬件加速技术进行简单介绍,其中上层实现基于 android  6.0分析。
安卓的硬件加速是自安卓3.0(API 11)之后才有的,安卓2D绘制支持硬件加速,但因为启用硬件加速需要增加资源,所以将会消耗更多的RAM。

在API14之后(包括14),硬件加速默认是开启的 ,侧面也说明,从11-13默认是关闭的,不过这个现在我们已经不考虑了,毕竟现在开发都不考虑那么低版本的手机了。启用硬件加速的最简单方式就是整个application都启用,如果只是使用标准的view或者drawable,那么应该不会产生不好的绘制效果。但是,因为硬件加速并不支持所有的2D绘制操作,如果你的应用有自定义的view或者调用某些绘制函数,启用硬件加速可能会对你的应用有一些影响,比如看不见一些元素或者呈现错误的像素,所以为了解决这个不兼容的问题,google大佬们的建议是,通过真机上启用硬件加速测试,遇到问题的话对以下四个级别进行控制,我们可以选择启用或者不启用硬件加速:
Application级别:
在安卓manifest文件,添加下列属性到<application>标签就可以给 整个 应用添加硬件加速:

Activity级别:
如果不想全局都启用硬件加速,那么个别Activity可以不指定硬件加速,在Activity级别启动或者不启用硬件加速,你可以<activity>标签指定android:hardwareAccelerated属性

window级别:
如果需要更细粒度的控制,可以用以下代码为一个window启用硬件加速

PS :目前还 不允许 在window级别 关闭 硬件加速的
view级别:
你可以在运行时对指定的View关闭硬件加速

第二个参数是Paint
或者在xml中的控件属性中,使用android:layerType=”software”来关闭硬件加速:比如

PS:因为 硬件加速需要加载系统资源, 目前还 不允许 运行时 启用 硬件加速 , View layers还有一些函数是不支持硬件加速的。
判断一个View是否开启硬件加速
有时候我们想知道应用是否开启了硬件加速,尤其是对于自定义View的情景,如果你的应用有很多的自定义绘制并且不是所有的操作都支持新的绘制管线时(硬件加速)。那么这两个不同的方法就变得特别的有用,可以检测应用是否是启用硬件加速:

View.isHardwareAcclerated()  如果 View是依附到启动了硬件加速的window 返回true

Canvas.isHardwareAccelerated 如果canvas是硬件加速的 返回true

但是,强烈建议使用Canvas.isHardwareAcclerated代替View.isHardwareAcclerated,因为View的这个方法真的非常不靠谱,即使这个View是依附在一个硬件加速的Window上,但是仍然可以使用一个不启用硬件加速的Canvas进行绘制,比如当我们把View绘制到bitmap上的时候。


不支持的绘制操作

当启用了硬件加速后,2D渲染管线支持大部分的canvas的常用绘制操作和一些不常用的操作,分别列举一下,其实我们也只有在自定义View的时候才担心canvas调用的函数会不会不支持硬件加速,所以我们只需要真正用到的时候查阅一下即可。

View Layers
在android的所有版本中views可以离屏渲染,使用view的绘制缓存或者通过使用Canvas.saveLayer()。离屏缓存,或者图层,有几种用途。你可以使用它们获得更好的显示效果,当对一些复杂的views使用动画效果或者一些合成效果,比如,你可以 使用 Canvas.saveLayer() 实现渐变效果来临时渲染一个view到一个layer,然后把不透明的元素合成到屏幕上。

android3.0开始,使用layers的时候有更多的控制方法了,通过View.setLayerType()函数,这个API有两个参数:layer的类型,和一个可选的 描述layer如何合成的Paint对象 ,你可以使用Paint参数来给layer添加Color Filter,指定混合模式,或者不透明度,可以选择以下三种layer type:
LAYER_TYPE_NONE :view只会普通地进行渲染,并且不会使用离屏缓存回退,这是默认的行为。
LAYER_TYPE_HARDWARE :如果应用启动了硬件加速,那么这个view就会使用硬件里面的texture渲染,利用GPU来加速渲染,如果应用不能够硬件加速,那么它的效果就和LAYER_TYPE_SOFTWARE一样。
LAYER_TYPE_SOFTWARE :这个view将会使用CPU来渲染到一个bitmap里。 如果 对某个View设置 View  . setLayerType(View. LAYER_TYPE_SOFTWARE , null ); 关闭硬件加速以后, 这个view将会使用CPU来渲染到一个bitmap里,并且 系统会把当前view转换后的bitmap保存,导致内存使用非常大, 所以在离开页面后最好清空View的内容并且调用 View  . destroyDrawingCache();释放 bitmap占用的缓存,否则多开几个页面就内存溢出了, 特别是对WebView和ImageView关闭硬件加速尤为需要注意这个问题。
texture :纹理,在3D游戏开发里面叫做贴图,存放图片到texture里面,运行时会读取,而在这里当我们需要重绘的时候也是一样的原理,从硬件中读取纹理然后进行绘制。
这几种类型的layer取决于你的用途:
Performance :使用一个硬件图层类型来渲染view到硬件中的texture,自从view被渲染到一个图层,它的绘制代码就不再被执行,直到view调用invalidate方法,一些动画,例如alpha动画,使用GPU来实现就可以高效地直接作用于图层上。
Visual effects :使用一个硬件或者软件图层类型,还有一个Paint对view进行一些特殊的处理,比如,你可以使用黑色和白色通过ColorMatrixColorFilter来绘制一个view。
Compatibility :使用一个软件图层类型来强迫一些view使用软件来渲染,如果一个view是硬件加速的(比如,如果你整个应用都是硬件加速的),那么就会出现渲染问题,最简单的解决方式就是限制硬件渲染管道(关闭View的硬件加速)。
View layer和animations

当你的应用是硬件加速的,硬件图层类型可以传达更快和更加顺滑的动画,当你在处理的是一个复杂的又很多绘制操作的view的时候,运行一个动画不总是60帧每秒的。可以通过使用硬件层来渲染view到一个硬件的texture中来优化这个问题,硬件texture可以用来对view进行动画,排除开始动画的时候需要重绘自己的View,view不会重新重绘除非你改变它的属性,然后调用invalidate()。如果你运行一个动画在你的应用上,但是得不到一个你想要的顺滑结果,考虑启用硬件加速在你的动画view上。当view从硬件图层回退的时候,它的一些属性会通过图层合成到屏幕上的方式进行处理,设置这些属性将会更加高效,因为它不需要view重绘或者无效化,下面的一些属性可以通过这种方式来合成到屏幕上,调用这些属性的setter方法就可以在目标view上实现而不需要重绘。这个过程利用GPU优秀的运算能力完成,不消耗CPU。
alpha:改变图层的不透明度
x,y,translationX,translationY:改变图层的位置
scaleX,scaleY:改变图层的大小
rotation,rotaionX,rotationY:改变图层在三维空间的排列方向
pivotX,pivotY:改变图层的转移点

这些属性都是同样的用法,当一个view使用ObjectAnimator,如果你想要访问这些属性,调用这些属性的getter和setter,比如,为了修改alpha属性,调用setAlpha,接下来的代码片段展示了最有效的方式来围绕Y轴旋转一个view:
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator.ofFloat(view, "rotationY", 180).start();

因为硬件层消耗video存储,所以强烈建议启用它们只有在动画开始时,并且当动画完成的时候 关闭它们 ,你可以完成这个通过使用动画监听器,这一个比较细节,但能够对View进行优化,毕竟手机内存这么少
View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "r
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值