聊聊SurfaceView和TextureView

3,864 阅读3分钟

播放视频或者渲染其他的动画的时候,有两个View组件可供选择,SurfaceView和TextureView,GLSurfaceView是SurfaceView是子类,这儿还是归类到SurfaceView中吧。

  • SurfaceView实现机制
  • 双缓冲机制
  • TextureView实现机制
  • TextureView和SurfaceView的优缺点

1.SurfaceView实现机制

SurfaceView继承自View,所以它也是一个View。但是这个View和普通的View有点不同。 SurfaceView有自己的Surface,在Android中,一个View有自己的Surface,在WMS中中就有对应的WindowState,对应在SurfaceFlinger中就有Layer。

一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DecorView,也就是根结点视图,才是对WMS可见的。这个DecorView在WMS中有一个对应的WindowState。相应地,在SurfaceFlinger中对应的Layer。而SurfaceView自带一个Surface,这个Surface在WMS中有自己对应的WindowState,在SurfaceFlinger中也会有自己的Layer。虽然SurfaceView在Application端它仍在View hierachy中,但在Server端(WMS和SurfaceFlinger)中,它与宿主窗口是分离的。

SurfaceView为什么要这么设计?
优点:这样的好处是对这个Surface的渲染可以放到单独线程去做,渲染复杂的动画不会影响主线程的的响应。

缺点:因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,也不能放在其它ViewGroup中,一些View中的特性也无法使用。

2.双缓冲机制

简单阐述一下:

  • 什么是无缓冲
  • 什么是单缓冲
  • 什么是双缓冲

不用画布,直接在窗口上进行绘图叫做无缓冲绘图。

用了一个画布,将所有内容都先画到画布上,在整体绘制到窗口上,就该叫做单缓冲绘图,那个画布就是一个缓冲区。

用了两个画布,一个进行临时的绘图,一个进行最终的绘图,这样就叫做双缓冲绘图。

SurfaceView自身就实现了双缓冲,通俗来讲就是有两个缓冲区,一个后台缓冲区和一个前台缓冲区,每次后台缓冲区接受数据,当填充完整后交换给前台缓冲,这样就保证了前台缓冲里的数据都是完整的。 双缓冲:SurfaceView在更新视图时用到了两张Canvas:

  • frontCanvas:实际显示的canvas
  • backCanvas:存储的是上一次更改前的canvas

当然效率更好的方法是frontCanvas和backCanvas在每一次绘制完了之后会交换,frontCanvas变成backCanvas,backCanvas变成frontCanvas。

双缓冲的优势非常明显:

  • 提高渲染效率
  • 可以避免刷新频率过高而出现的闪烁现象

3.TextureView实现机制

在Android4.0(API level 14)中引入,与SurfaceView一样继承View,它可以将内容流直接投影到View中,它可以将内容流直接投影到View中,可以用于实现Live preview等功能。

  • 和SurfaceView不同,不在WMS中单独创建窗口,而是作为View hierachy中的一个普通view,因此可以合其他普通View一样进行移动,旋转,缩放,动画等变化。
  • 和SurfaceView不同,TextureView必须在硬件加速的窗口中。
  • 它显示的内容流数据可以来自Application进程或是远端进程。
  • TextureView继承自View,它与其它的View一样在View hierachy中管理与绘制。TextureView重载了draw()方法,其中主要SurfaceTexture中收到的图像数据作为纹理更新到对应的HardwareLayer中。

优点:支持移动、旋转、缩放等动画,支持截图
缺点:必须在硬件加速的窗口中使用,占用内存比SurfaceView高,在5.0以前在主线程渲染,5.0以后有单独的渲染线程。

4.TextureView和SurfaceView的优缺点

SurfaceViewTextureView
内存
耗电
绘制效率及时1 ~ 3帧的延迟
截图不支持支持
动画不支持支持

不过GLSurfaceView是SurfaceView的子类,除了拥有SurfaceView的优点,GLSurfaceView也支持截图和动画操作。