surface.nativeUnlockCanvasAndPost发生IllegalArgumentException错误的解决方法

记录SurfaceView使用的一个错误解决方法。

错误打印:

09-03 20:04:49.543 15962-16033/com.dway.mediaplayer E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -19
    queueBuffer (handle=0x7f789d0d20) failed (No such device)
    
    --------- beginning of crash
09-03 20:04:49.544 15962-16033/com.dway.mediaplayer E/AndroidRuntime: FATAL EXCEPTION: Thread-3
    Process: com.dway.mediaplayer, PID: 15962
    java.lang.IllegalArgumentException
        at android.view.Surface.nativeUnlockCanvasAndPost(Native Method)
        at android.view.Surface.unlockSwCanvasAndPost(Surface.java:347)
        at android.view.Surface.unlockCanvasAndPost(Surface.java:328)
        at android.view.SurfaceView$4.unlockCanvasAndPost(SurfaceView.java:1045)
        at com.dway.DrawView.draw(DrawView.java:82)
        at com.dway.DrawView.run(DrawView.java:46)
        at java.lang.Thread.run(Thread.java:761)

代码:

package com.dway.player;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

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

    private SurfaceHolder mSurfaceHolder;
    private Canvas mCanvas;
    private Path mPath = new Path();
    private Paint mPaint = new Paint();
    private boolean mIsDraw;


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

    private void initView() {
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);
    }

    @Override
    public void run() {
        while (mIsDraw) {
            draw();
        }
    }

    @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;
    }

    //解决错误增加的方法
    public void exit(){
        mIsDraw = false;
    }

    private void draw() {
        try {
            mCanvas = mSurfaceHolder.lockCanvas();
            mCanvas.drawColor(Color.WHITE);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(10);
            mPaint.setColor(Color.BLACK);
            mCanvas.drawPath(mPath, mPaint);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (mCanvas != null) {
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mPath.moveTo(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            mPath.lineTo(x, y);
            break;
        case MotionEvent.ACTION_UP:
            break;
        }
        return true;
    }

}  

初看这代码好像没什么问题,但是当手指一次在屏幕上滑动很久之后,点击返回键退出就会出现错误,而且错误是native下的错误。

Activity跑了onPause后已经退出视野,并且堆栈下面的一个Activity也已经onResume了,但是SurfaceView更新线程还未停止,因为SurfaceView要等到回调destroy才停止,所以可能导致unlockCanvasAndPost方法出错,具体怎么出错还不知。

但是还是可以解决的,增加了exit方法,并且在Activity的finish方法中把绘制线程先停掉,这样就没问题了。

@Override
    public void finish() {
        super.finish();
        DrawView drawView = findViewById(R.id.draw_view);
        drawView.exit();
    }

 

有知道具体原因的可以告知下,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值