Android的SurfaceView的使用及其模板(View的孪生兄弟)

SurfaceView与View的区别

一般情况下,View可以满足我们大多数的绘画要求.但是有些时候View本身的限制限制了开发的需求.因为View是通过刷新来重新绘图的,Android系统通过发送VSYNC信号来进行屏幕的绘制,刷新的时间为16ms.如果绘图能在16ms内完成, 那么View是 完成可以胜任的,用户在视觉上不会有任何的卡顿.
但是例如游戏跟视频处理之类的,onDraw里面有复杂繁琐的运算,造成了16ms内不能完成一次onDraw,那么就会引起卡顿的效果,并带有类似"skipped xxx frames!The application may be doing too much"的警告。

为什么引入SurfaceView

就是为了避免上述问题,于是引入了SurfaceView
SurfaceView与View的主要区别:

  • View主要是适用于主动更新的情况下,而SurfaceView主要是被动刷新.并且更频繁
  • View在主线程中刷新,而SurfaceView则则是新开子线程去刷新.
  • View在绘图中没有实现双缓冲机制,而SurfaceView底层有实现.

总结:需要大量频繁刷新的View就建议使用SurfaceView来替代

SurfaceView的代码模板

对于SurfaceView来说,有一套比较通用的模板,绘画代码主要是draw里面的注释那个位置

package com.example.customview;

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

public class SurfaceViewSampleView extends SurfaceView implements Callback {
    
    private SurfaceHolder   mHolder;
    private Canvas          mCanvas;
    private boolean         drawAble    = false;
                            
    public SurfaceViewSampleView(Context context) {
        this(context, null);
    }
    
    public SurfaceViewSampleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public SurfaceViewSampleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        
        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        setKeepScreenOn(true);
    }
    
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
    }
    
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        drawAble = true;
        new Thread() {
            public void run() {
                while (drawAble) {
                    draw();
                }
            };
        }.start();
        
    }
    
    protected void draw() {
        try {
            mCanvas = mHolder.lockCanvas();

            //绘画的代码
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mHolder.unlockCanvasAndPost(mCanvas);
        }
    }
    
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        drawAble = false;
    }
    
}

你可能感兴趣的:(Android的SurfaceView的使用及其模板(View的孪生兄弟))