Android audio and video development series-SurfaceView introduction

Get into the habit of writing together! This is the sixth day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

SurfaceView

SurfaceViewInherited from the source code , but there are many differences between Viewthe internal implementation SurfaceViewand others . The main function is to provide a direct drawing surface embedded in the view structure, which actually does the drawing ability . Therefore , it is separate from the host window. Under normal circumstances, the windows share the same one , but also correspond to one , and all share the same one . Therefore , it is independent, which is equivalent to being separated from the drawing of the host window without interfering with each other.ViewSurfaceViewSurfaceSurfaceViewViewWindowWindowSurfaceViewSurfaceSurfaceViewSurface

difference

difference SurfaceView View
draw The structure is in the View, but the drawing surface is independent. Internally has its own Canvas for drawing operations Shares the same drawing surface as the host window
refresh Window refresh does not require redrawing the host window Any child element or partial refresh will cause the entire view structure to be redrawn
thread The thread is independent and does not affect the frequent refresh of the main thread using the interface Use on the main UI thread
operate The lower version does not support animations such as translation, zooming, and rotation, and does not have View property control can operate normally
refresh Controllable refresh rate, double cache mechanism Only refresh updates on the main thread

Double buffer mechanism

SurfaceViewParse the video stream into a frame of image data display. For example, after one frame of image is displayed, waiting for the next frame of image may not be parsed in time. In this case, the picture will not be smooth. This situation can be avoided by using double buffering. It can be understood that double buffering means that two threads take turns to parse the video stream image data and perform parsing and rendering operations alternately to ensure that the video stream can be played smoothly.

SurfaceHolder

SurfaceViewThe double buffering mechanism actually consumes more system memory. Therefore, when SurfaceViewit is not visible, it will be destroyed SurfaceHolderto reduce memory overhead. So there is a SurfaceHolderway addCallbackto monitor the SurfaceHolderstatus.

  • void surfaceCreated(@NonNull SurfaceHolder holder); create callback
  • void surfaceChanged(@NonNull SurfaceHolder holder, @PixelFormat.Format int format, @IntRange(from = 0) int width, @IntRange(from = 0) int height); 修改回调
  • void surfaceDestroyed(@NonNull SurfaceHolder holder); destroy callback

use

Custom inheritance SurfaceViewallows you to customize what is drawn. When the creation is SurfaceHoldersuccessful , call the acquired canvas surfaceCreatedin the callback and lock it, and then draw the content. After the drawing is finished, call release and submit the canvas change information, so that the new data can be displayed on the canvas.lockCanvasSurfaceHolderunlockCanvasAndPost

public class SurfaceViewTest extends SurfaceView implements SurfaceHolder.Callback{
    private SurfaceHolder mSurfaceHolder;
    private Canvas mCanvas;
    private Paint paint;

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

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

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

    private void init() {
        mSurfaceHolder = getHolder(); // 初始化
        mSurfaceHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 创建成功后就能通过线程绘制自定义内容
        new Thread(new Runnable() {
            @Override
            public void run() {
                draw();
            }
        }).start();
    }
    private void draw() {
        try {
            mCanvas = mSurfaceHolder.lockCanvas();
            mCanvas.drawCircle(500,500,300,paint);
            mCanvas.drawCircle(100,100,20,paint);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (mCanvas != null)
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
        }
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {}
}
复制代码

Guess you like

Origin juejin.im/post/7086047678727585822