Android TextureView与SurfaceView的相遇

一、认识TextureView
1、TextureView是什么?
TextureView是android4.0引入的,用于承载显示数据流的View。如本地Camera采集的预览数据流和视频通话模块从网络包里解出实时视频数据流。

2、TextureView怎么使用?

 mTextureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
    
    
            override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {
    
    
            }

            override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {
    
    
            }

            override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean {
    
    
                     
                return true
            }

            override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
    
    
                mCamera = Camera.open()
                val previewSize = mCamera.getParameters().getPreviewSize()
                mTextureView.layoutParams = FramLayout.layoutParams(preveiwSize.width,previewSize.height,Gravity.CENTER))
                mCamera.previewTexture = surface
                mCamera.startPreveiw()
                mTextureView.setAlpha=1.0f
                mTextureView.setRotation=45.0f
            }
        }

onSurfaceTextureAvailable回调中拿到SurfaceTexture,并把他设置给camera,作为承载、预览数据流的载体。
onSurfaceTextureDestroyed中关闭预览,释放camera资源,返回true。

3、用途
TextureView像一般的View,像TextView那样能被缩放、平移,也能加上动画。TextureView只能开启硬件加速的window中使用,并且消费的内存要比SurfaceView多,并伴随着1-3帧的延迟。

二、认识SurfaceVeiw
1、SurfaceVeiw是什么?
SurfaceView在自己独立的线程中绘制,不会影响到主线程,一方面可以实现复杂而高效的UI,另一方面又不会导致用户输入得不到及时响应。 内部使用双缓冲机制,画面更流畅。相比于TextureView,它内存占用低,绘制更及时,耗时也更低,但不支持动画和截图。
2、SurfaceVeiw的使用

创建SurfaceVeiw

public class SurfaceViewTest extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    
    
    public SurfaceViewTest (Context context) {
    
    
        this(context, null);
    }

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

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

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    
    
       //创建
    }

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

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

    @Override
    public void run() {
    
    
        //子线程
    }
}

前面三个构造函数的写法和自定义View是相同的,接下来的三个方法分别在SurfaceView创建、改变、销毁的时候进行调用,最后的run()方法中写我们子线程中执行的绘图逻辑即可。

初始化SurfaceVeiw

private SurfaceHolder mSurfaceHolder;
//绘图的Canvas
private Canvas mCanvas;
//子线程标志位
private boolean mIsDrawing;

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

public SurfaceViewTest (Context context, AttributeSet attrs, int defStyleAttr) {
    
    
    super(context, attrs, defStyleAttr);
    //在三个参数的构造方法中完成初始化操作
    initView();
}

SurfaceHolder类
这里用到了一个类SurfaceHolder,可以把它当成 surface的控制器,用来操纵surface。处理它的Canvas上画的的效果和动画,控制表面,大小,像素等

几个需要注意的方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback);
// 给SurfaceView当前的持有者一个回调对象。
(2)、abstract Canvas lockCanvas();
// 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
(3)、abstract Canvas lockCanvas(Rect dirty);
// 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。
// 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。
(4)、abstract void unlockCanvasAndPost(Canvas canvas);
// 结束锁定画图,并提交改变。

使用surfaceview

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

private SurfaceHolder mSurfaceHolder;

//绘图Canvas
private Canvas mCanvas;
//子线程标志位
private boolean mIsDrawing;

    public SurfaceViewTest (Context context) {
    
    
        this(context, null);
    }

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

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

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    
    
       //创建
       mIsDrawIng = true;
       //开启子线程
       new Thread(this).start();
    }

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

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

    @Override
    public void run() {
    
    
        //子线程
         while (mIsDrawing){
    
    
            drawSomething();
        }
    }

//绘图逻辑
    private void drawSomething() {
    
    
        try {
    
    
            //获得canvas对象
            mCanvas = mSurfaceHolder.lockCanvas();
            //绘制背景
            mCanvas.drawColor(Color.WHITE);
            //绘图
        }catch (Exception e){
    
    

        }finally {
    
    
            if (mCanvas != null){
    
    
                //释放canvas对象并提交画布
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }

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


猜你喜欢

转载自blog.csdn.net/hjjdehao/article/details/109010105