播放视频或者渲染其他的动画的时候,有两个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的优缺点
SurfaceView | TextureView | |
---|---|---|
内存 | 低 | 高 |
耗电 | 低 | 高 |
绘制效率 | 及时 | 1 ~ 3帧的延迟 |
截图 | 不支持 | 支持 |
动画 | 不支持 | 支持 |
不过GLSurfaceView是SurfaceView的子类,除了拥有SurfaceView的优点,GLSurfaceView也支持截图和动画操作。