1. 什么是SurfaceView?

Surface意识就是表面。那么它就是指一个在表层的View对象。为什么说是在表层呢,这是因为他有点特殊跟其他的View不一样。在这里拿TextView作为一个对比。TextView为代表作为Android的普通控件,它们的UI绘制实在应用程序的主线程中进行的。但是如果你的UI很复杂或者实时性很强,那么就有可能造成主线程的阻塞(因为应用主线程除了处理UI绘制外,还要处理用户的触摸事件),从而会导致程序出现ANR异常闪退。

就这样,SurfaceView就顺应时事出现了。继承了TextView的绘制思想,又解决了UI很复杂时可能造成的主线程阻塞问题。虽然Surface继承自View,但拥有着独立的surface,就是它不与它的宿主窗口共享一个surface,可以单独开启一个子线程进行绘制,并不会占用主线程的资源,这样绘制效率就很高。因此游戏,视频播放,直播都可以用SurfaceView来实现。SurfaceView有两个子类GLSurfaceView和VideoView。

官方对SurfaceView有一个解释,我翻译了一下大概是这样的一个意思:由于绘图表面只是在Z轴上有序排列的,因此它在宿主窗口背后持有了SurfaceView的对象引用;正是如此,SurfaceView在Z轴上挖了个“孔”,以便于展示绘图表面上所绘制的UI。

我画一张图也许会更好理解一点。

android surfaceview 显示bitmap android surfaceview原理_UI

其实并不是在SurfaceView在Z轴上真正的对宿主窗口表面挖了个洞,实际上,只是在它的宿主Activity窗口上设置了一块透明区域罢了。说完SurfaceView的实现原理再说一下它的用法。

 

  1. 如何使用SurfaceView?

       首先SurfaceView也是一个View,它肯定有它的生命周期。因为它需要开启一个子线程来执行绘制操作,所以我们可以在它的生命周期的初始化开辟这个新的子线程,然后开始执行绘制,当生命周期的结束阶段我们插入结束绘制线程的操作,这些都是由它内部一个SurfaceHolder对象完成。

  1. 创建SurfaceView:

           先创建一个类,继承自SurfaceView,然后实现两个接口:SurfaceHolder.Callback和Runnable。

           实现了这两个接口,就需要重写接口中的方法。对于第一个接口也就是 SurfaceHolder.Callback,需要实现三个方法:如下

SurfaceCreated(Surfaceholder holder)
SurfaceChanged(Surfaceholder holder, int format, int width, int height)
SurfaceDestoryed (SurfaceHolder holder)

这时你肯定有一个发现,这三个方法就是SurfaceView的生命周期方法。对于第二个接口Runnable接口,实现run()方法

  1. 初始化SurfaceView

在自定义的MySurfaceView的构造方法中,需要对SurfaceView进行初始化,包括SurfaceHolder的初始化,画笔的初始化,画笔的初始化等。在自定义的SurfaceView中,通常需要定义三个成员变量:

SurfaceHolder holder
Canvas mCanvas;//绘制的画布
boolean mIsDrawing;//控制绘画线程的标志位

那么SurfaceHolder有什么作用呢?

SurfaceHolder,顾名思义,它里面保存了一个对Surface对象的引用,而我们绘制方法本质上就是操控Surface。Surfaceholder因为保存了对Surface的引用,所以使用它来处理Surface的生命周期

  1. 使用SurfaceView

通过SurfaceHolder对象的lockCanvans()方法,我们可以获取当前的Canvas绘图对象。接下来的操作就和自定义View中的绘图操作一样了。需要注意的是这里获取到的Canvas对象还是继续上次的Canvas对象,而不是一个新的对象。因此。之前的绘图操作就会被保留。如果需要擦除可以在绘制前,用drawColor()方法进行q清屏操作。

  1. SurfaceView和View的区别:
  2. SurfaceView允许其他线程更新视图对象(执行绘制方法)而View不允许这么做,它只允许在UI线程更新视图对象。
  3. SurfaceView是放在其他最底层的视图层次中,所有其他视图层都在它上面,所以在它之上可以添加一些层,而且它不能是透明的。
  4. 它执行动画效率比View高,而且可以控制帧数。
  5. SurfaceView在绘图时使用了双缓冲机制,而View没有。

 双缓冲机制 :