Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-11-28:谈一谈SurfaceView与TextureView的使用场景和用法?

MoJieBlog opened this issue · comments

2019-11-28:谈一谈SurfaceView与TextureView的使用场景和用法?

SurfaceView专门提供了嵌入视图层级的绘制界面
TextureView更像是一般的View,像TextView那样能被缩放、平移,也能加上动画

1、频繁绘制和对帧率要求比较高的需求,比如拍照、视频和游戏等
2、SurfaceView有独立的绘图表面,可以在子线程中进行绘制,缺点是不能够执行平移、缩放、旋转、透明渐变操作,TextureView的出现就是为了解决这些问题
3、SurfaceView的使用方法,大概是获取SurfaceHolder对象,监听surface创建,更新,销毁,创新一个新的线程,并在其中绘制并提交
4、TextureView并没有独立的绘图表面,在使用过程中,需要添加监听surfaceTexture是否可用,再做相应的处理

SurfaceView 只要是用于在子线程中被动刷新 绘制频率要求比较高小于16/ms 比如视频,游戏,直播场景
TextureView本身已经包含了SurfaceView的特性 但TextureView更像一般的View 可以像TextView那样能被缩放、平移,也能加上动画。

一、SurfaceView
SurfaceView 是一个可以在子线程中更新 UI 的 View,且不会影响到主线程。它为自己创建了一个窗口(window),就好像在视图层次(View Hierarchy)上穿了个“洞”,让绘图层(Surface)直接显示出来。但是,和常规视图(view)不同,它没有动画或者变形特效,一些 View 的特性也无法使用。

概括:

SurfaceView 独立于视图层次(View Hierarchy),拥有自己的绘图层(Surface),但也没有一些常规视图(View)的特性,如动画等。
SurfaceView 的实现中具有两个绘图层(Surface),即我们所说的双缓冲机制。我们的绘制发生在后台画布上,并通过交换前后台画布来刷新画面,可避免局部刷新带来的闪烁,也提高了渲染效率。
SurfaceView 中的 SurfaceHolder 是 Surface 的持有者和管理控制者。
SurfaceHolder.Callback 的各个回调发生在主线程。
二、GLSurfaceView
GLSurfaceView 继承 SurfaceView,除了拥有 SurfaceView 所有特性外,还加入了 EGL(EGL 是 OpenGL ES 和原生窗口系统之间的桥梁) 的管理,并自带了一个单独的渲染线程。

概括:
继承自 SurfaceView,拥有其所有特性。
加入了 EGL 管理,是 SurfaceView 应用 OpenGL ES 的典型场景。
有单独的渲染线程 GLThread。
单独出了 Renderer 接口负责实际渲染,不同的 Renderer 实现相当于不同的渲染策略,使用方式灵活(策略模式)。
三、SurfaceTexture
Android 3.0(API 11)新加入的一个类,不同于 SurfaceView 会将图像显示在屏幕上,SurfaceTexture 对图像流的处理并不直接显示,而是转为 GL 外部纹理。
概括:
SurfaceTexture 可以从图像流(相机、视频)中捕获帧数据用作 OpenGL ES 外部纹理(GL_TEXTURE_EXTERNAL_OES),实现无缝连接。
我们可以很方便的对这个外部纹理进行二次处理(如添加滤镜等)。
输出目标是 Camera 或 MediaPlayer 时,可以用 SurfaceTexture 代替 SurfaceHolder,这样图像流将把所有帧传给 SurfaceTexture 而不是显示在设备上。
使用 updateTexImage() 方法更新最新的图像。
四、TextureView
TextureView 是 Android 4.0(API 14)引入,它必须使用在开启了硬件加速的窗体中。除了拥有 SurfaceView 的特性外,它还可以进行像常规视图(View)那样进行平移、缩放等动画。

概括:
必须开启硬件加速(这个默认就是开启的)。
可以像常规视图(View)那样使用它,包括进行平移、缩放等操作。
TextureView 重载了 draw() 方法,主要是使用 SurfaceTexture 中收到的图像数据作为纹理更新到对应的 HardwareLayer 中。
通过 SurfaceTextureListener 接口让使用者知道 SurfaceTexture 的各种状态
五、SurfaceView 对比 TextureView
SurfaceView TextureView
内存 较低 较高
绘制 及时 1-3 帧延迟
耗电 较低 较高
动画和截图 不支持 支持
浅谈 SurfaceView、TextureView、GLSurfaceView、SurfaceTexture