安卓 SurfaceView 和 View 的区别和使用方法

Android 系统提供了 View 进行绘图处理,View 可以满足大部分的绘图需求,但在某些时候,View 通过刷新来重绘视图,Android 系统通过发出 vsync 信号来进行屏幕重绘,刷新的间隔时间为 16ms,如果在这个时间间隔内完成了你所需要执行的所有操作,那么在视觉上,就不会产生卡顿的感觉,而如果执行的操作逻辑太多,特别再需要频繁刷新的界面上,例如游戏界面,那么就会不断阻塞主线程,从而导致界面卡顿,为了避免这个问题,Android 系统提供了 surfaceView 组件来解决这个问题。surfaceView 和 View 的区别主要有下面几点:

  • View 主要适用于主动更新的情况,而 surfaceView 主要适用于被动更新,例如频繁的刷新。
  • View 在主线程中对画面进行刷新,而 surfaceView 通常会通过一个子线程来进行页面的刷新
  • View 在绘图时没有使用双缓冲机制,而 surfaceView 在底层实现机制上就已经实现了双缓冲机制。
    总结就是,如果你的自定义 View 需要频繁刷新,或者刷新时数据处理量很大,考虑用 SurfaceView 来替代 View。

surfaceView 的使用

  • 创建 SurfaceView,一般我们实现 SurfaceHolder.Callback, Runnable接口
    //surfaceView 的创建
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsDraw = true;
    }
    //surfaceView 的改变
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }
    //surfaceView 的销毁
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsDraw = false;
    }
 //runnable 的run 方法中,我们可以执行绘制的操作
    @Override
    public void run() {
        while (mIsDraw) {
            draw();
        }
    }
  • 初始化 surfaceView
mHolder = getHolder();
mHolder.addCallback(this);
//通过 lockCanvas 方法可以获得当前的 canvas 绘图对象,接下来,就可以与在 View 中进行的绘制操作一样了
mCanvas = mHolder.lockCanvas();
//通过 unlockCanvasAndPost 方法可以对当前画布内容进行提交。
mHolder.unlockCanvasAndPost(mCanvas);

下面是一个 surfaceView 使用的模板,基本上可以在这个基础上来修改满足大部分的绘图需求。

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

    private SurfaceHolder mHolder;
    private boolean mIsDraw;
    private Canvas mCanvas;

    public SurfaceViewDemo(Context context) {
        super(context);
        initView();
    }

    public SurfaceViewDemo(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

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

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SurfaceViewDemo(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }


    private void initView() {
        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        setKeepScreenOn(true);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsDraw = true;
        new Thread(this).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsDraw = false;
    }

    //runnable 的run 方法中,我们可以执行绘制的操作
    @Override
    public void run() {
        while (mIsDraw) {
            draw();
        }
    }

    private void draw() {
        mCanvas = mHolder.lockCanvas();
        //draw something

        mHolder.unlockCanvasAndPost(mCanvas);
    }
}

下面是一些 surfaceView 的实例源码的地址:https://github.com/MoveToNext/SurfaceViewDemo

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值