Make writing a habit together! This is the sixth day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

SurfaceView

SurfaceView from the source View inherited from the View, but internal implementation of SurfaceView and other views have many differences. The main purpose of SurfaceView is to provide a direct drawing Surface to embed into the view structure, but it’s the Surface that actually does the drawing. So the SurfaceView and the host window are separate. Under normal circumstances, the View of a Window shares the same Window, and the Window also corresponds to a Surface, so all views share the same Surface. Therefore, the SurfaceView has an independent Surface, which is equivalent to the separation of the host window drawing without interference.

The difference between

The difference between SurfaceView View
draw The structure is in the View, but the drawing surface is separate. It has its own Canvas inside for drawing operations Shares the same drawing surface as the host window
The refresh Window refresh does not require redrawing the host window Any child or local refresh causes the entire view structure to be redrawn
thread Thread independence, does not affect the main thread to use the interface frequently refresh Used in the UI main thread
operation The lower version does not support panning, zooming, rotation and other animations without View property control All can operate normally
The refresh It can control the refresh frequency and double cache mechanism Refresh updates only in the main thread

Double buffering mechanism

SurfaceView parses the video stream into frames of image data for display. For example, after a frame of image is displayed, waiting for the next frame of image may not be resolved in time. In this case, the picture will not flow smoothly. This can be avoided with double buffering, which is understood to be two threads taking turns parsing the video stream image data and alternating parsing and rendering operations to ensure that the video stream plays smoothly.

SurfaceHolder

SurfaceView dual buffering is actually a drain on system memory. Therefore, when the SurfaceView is not visible, the SurfaceHolder is destroyed to reduce memory overhead. Hence the SurfaceHolder addCallback method to listen for SurfaceHolder state.

  • void surfaceCreated(@NonNull SurfaceHolder holder); Create a callback
  • void surfaceChanged(@NonNull SurfaceHolder holder, @PixelFormat.Format int format, @IntRange(from = 0) int width, @IntRange(from = 0) int height); Modify the callback
  • void surfaceDestroyed(@NonNull SurfaceHolder holder); Destruction of the callback

use

Custom Inheriting SurfaceView allows you to customize the drawing content. When the SurfaceHolder is successfully created, a call to lockCanvas in the surfaceCreated callback retrieves the SurfaceHolder canvas, locks it, and draws the content. After drawing, unlockCanvasAndPost is called to release and commit the canvas changes, allowing the new data to be displayed on the canvas.

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(a) {
        mSurfaceHolder = getHolder(); / / initialization
        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) {
        // Once created, custom content can be drawn by thread
        new Thread(new Runnable() {
            @Override
            public void run(a) {
                draw();
            }
        }).start();
    }
    private void draw(a) {
        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) {}}Copy the code