google在api14之后就提供了对硬件加速的支持,使用硬件加速功能意味着,在图形的绘制过程中
可以通过使用GPU来完成,这样也会消耗更多的内存,有利有弊!!!
硬件加速的四个控制级别:
应用级别:
直接在application的标签中添加属性
android:hardwareAccelerated="true"
activity级别:
在application的标签中全局打开硬件加速,在不需要硬件加速的activity中关闭硬件加速
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
Window级别:
直接在代码中,对window的flags进行设置
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
view级别:
在这个级别的控制中,不能够打开硬件加速功能,系统只提供了关闭硬件加速的功能!!
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
判断当前view的绘制是否开启硬件加速功能
View.isHardwareAccelerated() 返回true代表开启硬件加速功能
Canvas.isHardwareAccelerated() 返回true代表开启硬件加速功能(在7.0源码中查看,返回值已经被固定写死返回为false)
在Android中,view的绘制分为两种绘制model,一种是开启硬件加速情况下的绘制model,另一种是普通情况下的绘制模型!!!
view的任何属性改变都会导致view的重新绘制!!
在普通情况下的绘制分为两个部分:
1、销毁当前视图层级。对应函数invalidate() ,调用这个函数会导致view层级被销毁,并且重新绘制!!!一般在view内容改变时候使用!!
2、根据根据当前视图重新绘制视图层级。
在这种model存在一定的缺陷:
1、如果一个view1位于view2之上,这里指的是层级关系,如果view1调用了invalidate进行重新绘制会导致view2也进行重新绘制,即使view2的内容没有发生改变,会出现过度绘制的情况!!!
2、view的重新绘制也可能因为父view的重新绘制触发,造成view的绘制不可控!!
开启硬件加速的view绘制模型:
1、销毁当前视图层级;
2、记录更新当前的显示列表;
3、绘制显示列表值屏幕中。
例如:如果在开启硬件加速的情况更改listview的背景色。
会执行一下步骤:
1、销毁当前视图层级;
2、记录当前的显示列表:一个listview;
3、更新当前的显示列表,一个listview,背景色的值更新为蓝色;
4、绘制当前显示列表,将listview绘制到屏幕中。
在此次的绘制过程中,将不会调用listview的onDraw方法,也就不会调用listview中item中没用子项的view的onDraw方法,
少了这么多重复绘制绘制的过程,难怪速度回变快!!!!(为什么google不在普通的绘制model中也是用这种方法)
在Android所有的版本中,view都可以在灭屏情况修改缓存的值,通过使用一个view的drawingCache,或者通过使用Canvas.saveLayer(),
例如可以通过使用Canvas.saveLayer()实现一个褪色效果,并在亮屏的显示出来!!!
对于view有些属性更改是可以很快生效的,因为这个属性的支持是有硬件层支持的!!!
例如透明度、layer的位置,layer的尺寸、layer的方向、layer的转换起始位置!!
由于开启硬件加速很耗费内存,所以google建议我们在开始动画的时开始硬件加速,在动画结束后关闭硬件加速(万幸,动画都有开始和结束的监听回调)
实例:
View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
view.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
animator.start();
关于UI设计的建议:
1、减少应用中view的数量
2、避免view的过度绘制;
3、不要在绘制的方法中创建渲染对象;
4、不要高频率修改view的形状;
5、不要频繁修改view中的bitmap;
6、设置透明度时,尽量使用硬件加速功能(如果设置的view的layer的很大的情况下)。
这是我的微信公众号,如果可以的话,希望您可以帮忙关注一下,这将是对我最大的鼓励了,谢谢!!