项目中越来越多的动画,越来越多的效果导致了应用性能越来越低。该如何提升。
在View播放动画的过程中每一帧都需要被重绘。如果使用view layers,就不用每帧都去重绘,因为View渲染一旦离开屏幕缓冲区就可以被重用。
而且,hardware layers会在GPU上缓存,这样就会让一些动画过程中的操作变得更快。通过hardware layers可以快速的渲染一些简单的转变(位移、选中、缩放、颜色渐变)。由于很多动画都是这些动作的结合,所以hardware layers可以显著的提高动画性能。
在View当中提供了三种类型的Layer type:
首先使用的前提是在清单文件中开启了硬件加速。否则将无法使用hardware layer。这一点在上面的文档中也有说明。
API也是非常简单的,直接使用View.setLayerType()就好。使用时应该只是暂时的设置Hardware Layer,因为它们无法自动释放。
基本的使用步骤:
view调用View.setLayerType(View.LAYER_TYPE_HARDWARE, null)方法。View.setLayerType(View.LAYER_TYPE_NONE, null)方法来进行清除。示例:
mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
animator.start(); 但是如果在4.0.x的版本中使用上面的代码会本亏,必须要把setLayerType放到Runnable中。如下:
mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//This will work successfully
post(new Runnable() {
@Override
public void run () {
setLayerType(LAYER_TYPE_NONE, null);
}
}
}
});
animator.start(); 如果你基于minSdkVersion 16以上并且使用ViewPropertyAnimator时,你可以使用withLayer()方法替代如上的操作:
mView.animate().translationX(150).withLayer().start();或者在api 14以上时使用ViewCompat.animate().withLayer()
这样做,你的动画就会变得更流畅!
你应该知道,事情没那么简单。
Hardware layers有着惊人的提升动画性能的能力。然而,如果滥用,它的危害更大。不要盲目的使用layers
hardware layers除了view渲染外还会执行更多的工作。缓存layer将会需要时间,因为首选第一步就需要两个过程: 先将这些view渲染到GPU的一个layer中然后GPU再渲染该layer到Window上。如果要渲染的View非常简单(例如一个纯色值),那么这样在初始化的时候就会增加Hardware Layer不必要的开销。view.invalidate(),那么layer就必须要重新渲染。经常的废弃hardware layers会比没有layers的情况下更糟糕,因为如同上面讲到的hardware layers在设置缓存时会有额外的开销。如果你需要经常的重新缓存layer,那就会有极大的损害。
这个问题也是非常容易出现的,因为动画经常有多个移动的部分。假如现在有一个三个部分移动的动画:
Parent ViewGroup —-> Child View1 (往左移动) —-> Child View2 (往右移动) —-> Child View3 (往上移动)
如果你只在父布局ViewGroup上设置一个layer,那就将经常的缓存失效,因为ViewGroup会随着子View不断地改变。然而对每个单独的子Views而言,他们只是在位移。这种情况下,最好是对每个子View上设置Hardware Layer(而不是在父布局上)。
再次重申,通常是对多个子View上适当的设置Hardware Layer,这样他们就不会在动画运行时失效。
在手机开发者选项中的显示硬件层更新(Show hardware layers updates)功能是追踪这个问题的开发利器。当View渲染Hardware Layer的时候闪烁绿色,它应该在动画开始的时候闪烁一次(也就是Layer渲染初始化的时候),然而,如果你的View在整个动画期间都是绿色,那就是遇到失效的问题了。hardware layers使用GPU内存,你当然不想出现内存泄漏的问题。所以你应该在必要的时候再去使用hardware layers,就想播放动画时。 这里也没有硬性规则。Android渲染系统是非常复杂的。就像所有性能问题一样,测试才是关键。通过使用“显示硬件层更新”开发者选项来确定layers问题之后,再优化。