美文网首页Android
SurfaceView 用法

SurfaceView 用法

作者: 莫库施勒 | 来源:发表于2019-03-13 12:18 被阅读0次

介绍

我们知道View是通过刷新来重绘视图,系统通过发出VSSYNC信号来进行屏幕的重绘,刷新的时间间隔是16ms,如果我们可以在16ms以内将绘制工作完成,则没有任何问题,如果我们绘制过程逻辑很复杂,并且我们的界面更新还非常频繁,这时候就会造成界面的卡顿,影响用户体验,为此Android提供了SurfaceView来解决这一问题。

SurfaceView 拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面。由于拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独立的线程中进行绘制。又由于不会占用主线程资源,SurfaceView 一方面可以实现复杂而高效的UI,另一方面又不会导致用户输入得不到及时响应。

我们知道普通的 Android 控件,例如 TextView、Button 等,它们都是将自己的UI绘制在宿主窗口的绘图表面之上,这意味着它们的UI是在应用程序的主线程中进行绘制的。一般来说,每一个窗口在SurfaceFlinger服务中都对应有一个Layer,用来描述它的绘图表面。对于那些具有SurfaceView的窗口来说,每一个SurfaceView在SurfaceFlinger服务中还对应有一个独立的Layer或者LayerBuffer,用来单独描述它的绘图表面,以区别于它的宿主窗口的绘图表面。SurfaceFlinger 服务把所有的 LayerBuffer 和 Layer 都抽象为 LayerBase,因此就可以用统一的流程来绘制和合成它们的UI。

SurfaceView 与 Activity 绘制
上图中 Activity 的 DecorView 及其中的两个TextView控件的UI都是绘制在 SurfaceFlinger 服务中的同一个Layer上面的,而 SurfaceView 的 UI 是绘制在 SurfaceFlinger 服务中的另外一个 Layer 或者 LayerBuffer 上的。

注意,用来描述SurfaceView的Layer或者LayerBuffer的Z轴位置是小于用来其宿主Activity窗口的Layer的Z轴位置的,但是前者会在后者的上面挖一个“洞”出来,以便它的UI可以对用户可见。实际上,SurfaceView在其宿主Activity窗口上所挖的“洞”只不过是在其宿主Activity窗口上设置了一块透明区域。

用法

public class SurfaceViewDemo extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    public SurfaceViewTemplate(Context context) {
        this(context, null);
        //在三个参数的构造方法中完成初始化操作
       initView();
   }

    public SurfaceViewTemplate(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

   private void initView(){
        mSurfaceHolder = getHolder();
        //注册回调方法
        mSurfaceHolder.addCallback(this);
        //设置一些参数方便后面绘图
        setFocusable(true);
        setKeepScreenOn(true);
        setFocusableInTouchMode(true);
   }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
           //创建
          new Thread(this).start();
   }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        //改变
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //销毁
    }

    @Override
    public void run() {
        //子线程
    }
}
<com.example.view.SurfaceViewDemo
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

原理图

SurfaceView.jpg

其中有部分方法已修改,需要日后验证

相关文章

网友评论

    本文标题:SurfaceView 用法

    本文链接:https://www.haomeiwen.com/subject/fokzpqtx.html