SufaceView与TexutreView的简单解析
Surface/SurfaceView/TextureView/SurfaceTexture
标签(空格分隔): android
Surface
可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图容器。
简单的说Surface对应了一块屏幕缓冲区,每个window对应一个Surface,任何View都要画在Surface的Canvas上。传统的view共享一块屏幕缓冲区,所有的绘制必须在UI线程中进行。
Surface中的Canvas成员,是专门用于供程序员画图的场所;1
2
3
4
5
6
7
8
9
10
11
12
13 其中的原始缓冲区是用来保存数据的地方;
Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原始缓冲区以及其它方面的内容。
Surface是用来管理数据的。(句柄)
PS:句柄是一种特殊的智能指针。当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。
## SurfaceView
```flow
object=>start: Object:>http://www.google.com
view=>start: View:>
surface=>start: SurfaceView:>
object(right)->view(right)->surface
SurfaceView是一个View,但他拥有自己的Surface
开发者一般所用的View都是在Canvas进行绘制,然后最顶层的View(通常是DecorView)的Canvas的数据信息会转换到一个Surface上。SurfaceFlinger会将各个应用窗口的Surface进行合成,然后绘制到屏幕上.
那为什么会有一个SurfaceView呢?
- 这是因为View的测量(Measure),布局(Layout)以及绘制(Draw)的计算量比较大。计算完以后再从Canvas转换成Surface中数据,然后再绘制屏幕,这个流程比较耗时。对于常规的UI绘制不会有什么问题,但是像Camera的预览以及视频的播放这样的应用场景来说就不可接受了。SurfaceView就是为了解决这个问题。SurfaceView内容不再是绘制在Canvas上,而是直接绘制在其持有的一个Surface上。由于省去了很多步骤,其绘制性能大大提高。而SurfaceView本身只是用来控制这个Surface的大小和位置而已。
- surfaceView是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。
SurfaceView的用法
SurfaceHolder.是对 SurfaceView 的 Surface 的包装.提供访问和控制SurfaceView内嵌的Surface相关的方法
SurfaceHolder.CallBack. 即Surface的监听器,它通过三个回调方法,让我们可以感知到Surface的创建、销毁或者改变
获取到 SurfaceView 对应的 SurfaceHolder,给 SurfaceHolder 添加一个 SurfaceHolder.callback 对象。
创建渲染线程对象
在子线程中开始在 Surface 上面绘制图形,使用 SurfaceHolder 的 lockCanvas()获取 Surface 上面指定区域的 Canvas,在该 Canvas 上绘制图形,绘制结束后,使用 SurfaceHolder 的 unlockCanvasAndPost()方法解锁 Canvas,并且让 UI 线程把 Surface 上面的东西绘制到 View 的 Canvas 上面
注意事项:
- surface 的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。
注意,如果 surface 上面有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件之间的透明效果,这会影响性能。 - 所有 SurfaceView 和 SurfaceHolder.Callback的方法都会在UI线程里调用,一般来说就是应用程序主线程。所以渲染线程所要访问的各种变量应该作同步处理。
TextureView
Texture类似SurfaceView,但但能像一般的View那样能被缩放、平移,也能加上动画。TextureView只能在开启了硬件加速的Window中使用,并且消费的内存要比SurfaceView多,并伴随着1-3帧的延迟。
SurfaceTextureListener 类似SurfaceHolder.CallBack.能够监听SurfaceTexture的创建.
序号 | 方法 | 描述 |
---|---|---|
1 | getSurfaceTexture() | This method returns the SurfaceTexture used by this view. |
2 | getBitmap(int width, int height) | This method returns Returns a Bitmap representation of the content of the associated surface texture. |
3 | getTransform(Matrix transform) | This method returns the transform associated with this texture view. |
4 | isOpaque() | This method indicates whether this View is opaque. |
5 | lockCanvas() | This method start editing the pixels in the surface |
6 | setOpaque(boolean opaque) | This method indicates whether the content of this TextureView is opaque. |
7 | setTransform(Matrix transform) | This method sets the transform to associate with this texture view. |
8 | unlockCanvasAndPost(Canvas canvas) | This method finish editing pixels in the surface. |