硬件加速
硬件加速是指利用设备的硬件资源来加速图形渲染和图像处理等操作,以提高应用程序的性能和用户体验。在Android系统中,硬件加速主要通过以下几种方式实现:
硬件加速可以通过利用设备的硬件资源来加速图形渲染和图像处理等操作,提高应用程序的性能和用户体验。
使用硬件加速优点:
在Android里,硬件加速专指把View中绘制的计算工作交给GPU来处理,这个绘制的计算工作通常指的是把绘制方法中的那些Canvas.drawXXX()变成实际的像素操作。
加速原理
在硬件加速关闭的时候,Canvas绘制的工作方式是把要绘制的内容写进一个Bitmap,然后在之后的渲染过程中,这个Bitmap的像素内容被直接用于渲染到屏幕。这种绘制方式的主要计算工作在于把绘制操作转换为像素的过程(例如由一句 Canvas.drawCircle() 来获得一个具体的圆的像素信息),这个过程的计算是由CPU来完成的。大致就像这样:
开启硬件加速后,Canvas的工作方式改变了,先把绘制的内容转为GPU的操作保存下来,然后交给GPU来完成显示工作。大致过程:
从上图可以看出,开启硬件加速后,绘制的计算工作由CPU交给GPU,不过这怎么就能起到加速作用,让绘制变快了呢?硬件加速能够让绘制变快,主要有三个原因:
关闭硬件加速时,绘制内容会被CPU转为实际的像素直接渲染到屏幕,这个·[实际的像素]·是由Bitmap承载的,在界面的某个View由于内容发生改变而调用invalidate()方法时,如果没有开启硬件加速,为了正确计算Bitmap的像素,这个View的父View、父View的父View乃至一直向上知道最顶级的View,以及所有和它相交的View,都需要被调用invalidate()来重绘,一个View的改变使得大半个界面甚至整个界面重绘一遍,这个工作量是非常大的。
开启硬件加速时,绘制的内容会被转换成GPU的操作保存下来(承载的形式成为DisplayList,对应的类也叫作DisplayList)转交给GPU。由于所有绘制的内容都没有变成最终的像素,所以它们之间是相互独立的,那么在界面内容发生改变时,只需把发生了改变的View调用invalidate()方法以更新它所对应的GPU就好,至于它的父View和兄弟View,只需要保持原样,那么这个工作量就很小了。
正是由于上面的原因,硬件加速不仅是由于GPU的引入提高效率,而且因为绘制机制的改变,而极大的提高了界面内容改变时的刷新效率。
硬件加速不止有好处,也会受到GPU绘制方式的限制,Canvas有些方法在硬件加速开启时会失效或者无法正常工作,比如:开启硬件加速,clipPath()在API18及以上系统中才有效,具体的API限制和API版本的关系如下图:
在开发Android应用时,需要考虑到设备的兼容性和性能差异,合理使用硬件加速功能。
硬件加速开启
android:hardwareAccelerated
这将启用应用程序的硬件加速功能。
android:hardwareAccelerated
或者在代码中使用以下方法来启用硬件加速:
getWindowsetFlagsWindowManagerLayoutParamsFLAG_HARDWARE_ACCELERATED WindowManagerLayoutParamsFLAG_HARDWARE_ACCELERATED
//View开启硬件加速view.setLayerType(LAYER_TYPE_HARDWARE, null);
view.setLayerType(LAYER_TYPE_SOFTWARE, null)方法的作用并不是关闭硬件加速,当它的参数为LAYER_TYPE_SOFTWARE的时候,可以顺便把硬件加速关掉而已;并且除了这个方法外,Android并没有提供专门的View级别的硬件加速开关,所以顺便成了一个开关硬件加速的方法。
setLayerType()方法的作用就是设置View Layer的类型。ViewLayer又称为离屏缓冲(off-screen Buffer),作用就是单独启用一块地方来绘制View,而不是使用绘制软件的Bitmap或者通过硬件加速的GPU,这块地方可能是一块单独的Bitmap,也可能是一块OpenGL的纹理(texture,OpenGL的纹理可以简单理解为图像的意思),具体取决于硬件加速是否开启。采取什么来绘制View不是关键,关键在于当设置了View Layer的时候,它的绘制会被缓存下来,而且缓存的是最终的绘制结果,而不是像硬件加速那样只是把GPU的操作保存下来再交给GPU去计算。通过这样更进一步的缓存方式,View的重绘效率进一步提高了:只要绘制的内容没变,那么不论是CPU绘制还是GPU绘制,都不用重新计算,只要用之前缓存的结果就可以了。
在进行移动、旋转等(无需调用 invalidate())的属性动画的时候开启Hardware Layer 将会极大地提升动画的效率,在动画过程中View本身并没有发生改变,只是位置或角度改变了,这种改变是可以由GPU通过简单计算就完成的,并不需要重绘整个View。所以在动画的过程中开启Hardware Layer,可以让本来就依靠硬件加速而变流畅了的动画变得更加流畅。实现方式大概是这样:
setLayerTypeLAYER_TYPE_HARDWARE ObjectAnimator animator ObjectAnimatorofFloat animatoraddListenernew AnimatorListenerAdapter { void onAnimationEndAnimator animation {setLayerTypeLAYER_TYPE_NONE }}animator
在对translationX translationY rotation alpha等无需调用invalidate()的属性做动画的时候方法才适用,因为方法本身利用的就是当界面不发生时,缓存未更新所带来的时间的节省。「不适用于基于自定义属性绘制的动画。」
总结
硬件加速指使用GPU来完成绘制的计算工作,从工作分摊和绘制机制优化两个角度提升了绘制速度。
硬件加速可以使用setLayerType()来关闭硬件加速,但这个方法其实是用来设置View Layer的:
View Layer可以加速无invalidate()时的刷新效率,但对于需要调用invalidate()的刷新无法加速。绘制所消耗的实际时间是比不使用View Layer时要高的,所以要慎重使用。
本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载者并注明出处:https://www.jmbhsh.com/zixun/35061.html