SurfaceView的入门(一)----初始surfaceView

转载:https://blog.csdn.net/rong_wz/article/details/51956463

转载:https://www.jianshu.com/p/acf574f08efc

转载:https://blog.csdn.net/android_cmos/article/details/68955134

什么是surface?           

         我们知道Activity是用了来显示界面的,那么Activity的界面是如何绘制出来的呢?这个肯定和Surface有关,但是博主是新手,具体关联就不清楚,博主自己理解,Surface就像屏幕上的一个画布,canvas是一位画家,paint就是一支笔,view其实就是由一位画家canvas还有一些关于view自身的事件的组成的一个对象,有了canvas,就可以往surface上面作画了,而每一个window对应一个Surface,任何View都是显示在Surface上的,传统的view共享一个surface,但因为view只能在ui线程更新,所以view里面的画手canvas消耗的时间是主线程出的(为什么?因为如果多线程操作ui,就会涉及到同步和锁之类的,这样子效率就不高,所以系统把所有ui操作都在主线程执行,当操作ui时候,如果判断不当前线程不是主线程,直接抛异常),因此,用传统ui做频繁的更新操作,会引起线程的阻塞,从而造成卡顿,严重会出现无响应,所以这个时候,需要surfaceView

什么是surfaceView?

   surfaceView本身继承于view,符合view的所有特性,但是还不够严谨,看下图。


              

     

    上图是SurfaceView源码,可以知道SurfaceView的创建会新建一个窗口,而这个newMyWindow(this)this就是指的surfaceView对象本身,从上面知道,surfaceView有自己的window,上面说了,每个window对应一个surface,所以SurfaceView内嵌了一个自己的Surface,所以SurfaceView和传统的view不是共用一个surface,并且和传统的view还有不同的是,view是绘制在suface之上的,但是surfaceView是绘制在surface中,意思就像,一般的view就像在琥珀上面画画,surfaceView就是琥珀里面的东西,另外,view的绘制用到的画手消耗的时间是在主线程里面出的,但是surfaceview画图,就像琥珀里面的东西,它不用外在的画上去所以不需要消耗主线程的时间,只需要内部的描绘出来,描绘出来的这段时间,可以用子线程来执行,所以surfaceView用来做游戏,录播播放还有一些频繁更新的操作,因此surfaceView你可以理解为只是一个改变surface画布大小和位置的一个view。.

 如何surfaceView?

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

      SurfaceView它的绘制原理是绘制前先锁定画布(获取画布),然后等都绘制结束以后在对画布进行解锁 ,最后在把画布内容显示到屏幕上。

      通常情况下,使用以下步骤来创建一个SurfaceView的模板:

  (1)创建SurfaceView

  创建自定义的SurfaceView继承自SurfaceView,并实现两个接口:SurfaceHolder.CallbackRunnable.代码如下

public class MySurfaceView extends SurfaceView implements Runnable,SurfaceHolder.Callback{

     通过实现这两个接口,就需要在自定义的SurfaceView中实现接口的方法,对于SurfaceHolder.Callback方法,需要实现如下方法,其实就是SurfaceView的生命周期:

 @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsDrawing = true;
        new Thread(this).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsDrawing = false;
    }

对于Runnable接口,需要实现run()方法,


 @Override
    public void run() {
        while (mIsDrawing){
            try {
                mCanvas = mHolder.lockCanvas();
                // draw sth绘制过程
            } catch (Exception e) {
            } finally {
                if (mCanvas != null)
                    mHolder.unlockCanvasAndPost(mCanvas);//保证每次都将绘图的内容提交
            }
        }
    }

(2)初始化SurfaceView

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

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

     SurfaceHolder,顾名思义,它里面保存了一个对Surface对象的引用,而我们执行绘制方法本质上就是操控Surface。SurfaceHolder因为保存了对Surface的引用,所以使用它来处理Surface的生命周期。(说到底 SurfaceView的生命周期其实就是Surface的生命周期)例如使用 SurfaceHolder来处理生命周期的初始化。

初始化代码如下:

 public MySurfaceView(Context context) {
        super(context);
        initView();
    }

    private void initView() {
        mHolder = getHolder();//获取SurfaceHolder对象
        mHolder.addCallback(this);//注册SurfaceHolder的回调方法
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);//保持屏幕常亮
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

(2)SurfaceView总体使用

package com.slide.aier.myview;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * Created by aier on 2018/6/23.
 */

public class MySurfaceView extends SurfaceView implements Runnable,SurfaceHolder.Callback{

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

    public MySurfaceView(Context context) {
        super(context);
        initView();
    }

    private void initView() {
        mHolder = getHolder();//获取SurfaceHolder对象
        mHolder.addCallback(this);//注册SurfaceHolder的回调方法
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);//保持屏幕常亮
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsDrawing = true;
        new Thread(this).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsDrawing = false;
    }

    @Override
    public void run() {
        while (mIsDrawing){
            try {
                mCanvas = mHolder.lockCanvas();
                // draw sth绘制过程
            } catch (Exception e) {
            } finally {
                if (mCanvas != null)
                    mHolder.unlockCanvasAndPost(mCanvas);//保证每次都将绘图的内容提交
            }
        }
    }
}



  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值