Android面试题----Android的硬件加速

在软件渲染时,即使只有一个View发生改变,也会遍历整个ViewTree来进行重绘,而其中大部分的绘图操作却没有发生任何变化。硬件加速,用来提高渲染速度,并且可以达到更顺畅的动画效果。
1)原理:
在硬件加速的渲染模型中有一个重要的核心类:DisplayList,每个View内部都会维护一个DisplayList。
在不支持硬件渲染的版本中,系统是通过draw()或invalidate()方法去通知屏幕更新并重新渲染,这两个方法的区别只是实际处理绘制的方式不同。
支持硬件渲染的版本中,在打开硬件渲染后绘制View时,其中执行绘制的draw()方法会把所有绘制命令记录到一个新的显示列表(DisplayList),这个显示列表(DisplayList)包含了输出的View层级的绘制代码,但并不是加入到显示列表就立刻执行,当这个ViewTree的DisplayList全都记录完毕后,由OpenGLRender负责将Root View中的DisplayList渲染到屏幕上。而invalidate()方法只是在显示列表中记录和更新显示层级,去标记不需要绘制的View。

Android面试题----Android的硬件加速_第1张图片

上图中,使用DisplayList,如果只有一个View有变化,只需要重绘这个View,因此可以减少很多的绘图操作次数,仅仅需要重绘一个View的DisplayList,能显示提高渲染的效率。
但是,硬件渲染模型也存在一个问题,当一个View和脏区域有交集时,不一定会执行draw()方法。需要确保Android系统记录了一个View的显示列表,如果没有调用invalidate()方法,即使View发生了变化,看起来也会是相同的,这点需要注意。
2)硬件加速控制级别
如果应用程序中只使用了标准View或Drawable,就可以为整个系统打开硬件加速的全局设置。但并不是所有2D绘制的操作都支持硬件加速,因此开启全局硬件回事可能会对使用自定义控件造成影响,为了避免这个问题,Android提供了一个级别控制,这样可以选择启动或者禁用以下不同级别的硬件加速。可以控制的级别有:
(1)Application级别
在Manifest文件中添加属性,整个应用使用硬件加速:

(2)Activity级别
对Activity进行单独控制。可以启动或者禁用一个Activity的硬件加速。

(3)Window级别
对某个window进行加速:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
(4)View级别
对指定的View控制硬件加速:
View.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
layType设置成Software,会将整个View绘制到一个Bitmap中,然后依然是通过硬件加速的方式将这个Bitmap绘制到Canvas。
代码中可以检查当前View是否已经硬件加速,可以使用View.isHardwareAccerated(),或者Canvas.isHardwareAccelerated()来得到结果。即使View是在一个已经加速的Window中,也可以使用没有硬件加速的Canvas进行绘制。
虽然硬件加速可以带来更好的绘制效果,但以下几点需要注意:
(1)在软件渲染时,可以使用重用的Bitmap的方法来节省内存,但是如果开户了硬件加速,这个方案就不起作用了。
(2)开启硬件加速的View在前台运行时,需要耗费额外的内存,加速的UI切换到后台时,产生的额外内存有可能不释放。
(3)当UI中存在过渡绘制时,硬件加速会比较容易发生问题,需要减少UI过度绘制。

====================================================

本文首发于微信公众号《Android面试专栏》,欢迎大家关注!!

Android面试题----Android的硬件加速_第2张图片
关注微信公众号《Android面试专栏》.jpg

你可能感兴趣的:(Android面试题----Android的硬件加速)