煎饼

煎饼为你分享Android有关的技术文章
不断分享,点滴积累,共同提高

关注微信公众号[developers]
更快的了解新的技术动态

使用硬件层(hardware layers)提高Android动画性能

能不能使用硬件层来提高动画的性能呢?

在动画进行时,视图(Views)的每一帧都会被重绘。如果使用view layers代替每帧都重绘,渲染到屏外缓冲区(off-screen buffer)的视图就可以被重用。

另外,hardware layers被缓存在GPU上,这让在动画过程中的一些操作变得更快。使用Layers会让简单的变化(translation,rotation,scaling and alpha)迅速的渲染。由于很多动画是以上四种的结合,所以layers能supercharge动画性能。

使用

layer API非常简单,调用View.setLayerType()方法即可.但你应该是暂时设置hardware layers,因为它并非都是有利于我们的操作的(更多内容在后面)。基本操作如下:

1、对你想要在动画中缓存的View调用view.setLayerType(View.LAYER_TYPE_HARDWARE,null).

2、播放动画

3、在动画结束后,通过View.setLayerType(View.LAYER_TYPE_NONE,null)清除缓存。

上面的过程代码操作如下:

// Set the layer type to hardware 
myView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
// Setup the animation
ObjectAnimator animator = ObjectAnimator.ofFloat(myView, View.TRANSLATION_X, 150);
// Add a listener that does cleanup 
animator.addListener(new AnimatorListenerAdapter() {  
  @Override
  public void onAnimationEnd(Animator animation) {
    myView.setLayerType(View.LAYER_TYPE_NONE, null);
  }
});

// Start the animation
animator.start();  

如果你的最小sdk版本(minSdkVersion)是16+并且你在使用ViewPropertyAnimator,可以使用现成的方法withLayer()替代上边的操作。

这样操作之后,正如上面所说,你的动画会更流畅。

警告

...你知道这并非易事。

使用hardware layer去加速动画性能是很奇妙的事。如果使用不当,就会得不偿失,所以不要盲目使用layers( Don't blindly apply layers.

First,在某些情况下,硬件层确实可能做更多的工作而不仅仅是简单的视图渲染。缓存层级会花费时间,因为第一遍是一个两步的过程:首先视图渲染到GPU上的一个层级,然后GPU会将这个层级给渲染到视窗。如果视图的渲染过于简单,那么在初始化时,hardware layer就可能会增加不必要的冗杂了。

Second,因为所有的视图都做了缓存,那么就会存在缓存失效的情况。如果在播放动画的过程中其他程序调用了view.invalidate(),就会重新渲染。持续无效的硬件层会比没有设置更糟糕,因为在进行缓存的时候硬件层会增加开销。

其实这个问题探究起来非常的容易,因为我们在用到动画时,经常会用到AnimationSet来处理多个动画,或者多个方向上的动画。假设你要实现一个三个方向上运动的动画:

Parent ViewGroup  
--> Child View 1 (translates left)  
--> Child View 2 (translates right)  
--> Child View 3 (translates up) 

如果你在父ViewGroup上设置了单个层级(layer),就会不断的缓存无效的layer,因为(作为一个整体)ViewGroup会因为它的子视图而持续不断的变化。每个独立的视图,仅仅是在移动。在这种情况下,最好的是对每个子View设置hardware layer而不是对父视图设置hardware layer。

重申一下,因为开始我不太明白这一点:通常更适合对多个视图(Views)设置hardware layers,因为在动画过程中他们都不会是无效的。

Third,hardware layers占用GPU存储,但是你不会允许任何的内存泄漏的情况。因此你要在必要的时候用hardware layers,比如在动画中。

总的来说,没有太难的地方。Android rendering system很复杂而且经常会让我吃惊。像所有的性能问题一样,实际测验才是关键。开发者设置里的“GPU呈现模式分析” 及 “显示硬件层更新”对确定硬件层是有帮助还是有损害非常有用。

Sample

Source Code 这个例子介绍了hardware layer的基本用法。

没有设置hardware layers,动画的渲染是糟糕的。因为由第一张图可以看出,它基本一直都是超过绿线的,相反设置了hardware layers的在第二张图中都没有超过绿线。第三张图表示的是设置了hardware layers但在动画过程中缓存失效的情况,反应的是不合理的使用hardware layers造成了性能的降低。

注:绿线表示的是渲染每一帧用时等于16ms的情况。

Hardware layers对动画性能的提升有很大作用,但需明确地使用它。

197

分享本文:

Android Dev Tools