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
SurfaceView
Inherited from the source code , but there are many differences between View
the internal implementation SurfaceView
and 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.View
SurfaceView
Surface
SurfaceView
View
Window
Window
Surface
View
Surface
SurfaceView
Surface
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
SurfaceView
Parse 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
SurfaceView
The double buffering mechanism actually consumes more system memory. Therefore, when SurfaceView
it is not visible, it will be destroyed SurfaceHolder
to reduce memory overhead. So there is a SurfaceHolder
way addCallback
to monitor the SurfaceHolder
status.
- 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 SurfaceView
allows you to customize what is drawn. When the creation is SurfaceHolder
successful , call the acquired canvas surfaceCreated
in 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.lockCanvas
SurfaceHolder
unlockCanvasAndPost
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) {}
}
复制代码