【问题标题】:Android Canvas locking throws IllegalArgumentExceptionAndroid Canvas 锁定抛出 IllegalArgumentException
【发布时间】:2012-01-16 04:15:01
【问题描述】:

我正在尝试实现我自己的自定义 SurfaceView,当触摸它时,它会在用户触摸屏幕的点绘制一个圆圈。但是,当我打电话给mSurfaceHolder.lockCanvas() 时,我得到了一个例外。每当画布锁定时,类似于非法参数的东西。示例代码发布在下面。

public class TapArea extends SurfaceView implements SurfaceHolder.Callback {
    private static final int TAP_RADIUS = 4;
    private boolean mLoaded = false;
    private Paint mTapPaint;
    private SurfaceHolder mSurfaceHolder;

    protected OnTouchListener mTouchEvent = new OnTouchListener() {
        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
            if (!mLoaded)
                return false;

            Canvas c = null;
            c = mSurfaceHolder.lockCanvas();
            drawTap(c, arg1);

            return true;
        }
    };

    public TapArea(Context context, AttributeSet attrs) {
        super(context, attrs);

        this.setOnTouchListener(mTouchEvent);
        mHandler = new Handler();
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);
        mTapPaint = new Paint();
    }

    public void drawTap(Canvas canvas, MotionEvent tap) {
        canvas.drawCircle(tap.getX(), tap.getY(), TAP_RADIUS, mTapPaint);
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        // TODO Auto-generated method stub
        mLoaded = true;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub

    }
}

以下是我不断收到的错误日志:

01-17 00:19:44.703: E/Surface(9731): Surface::lock failed, already locked
01-17 00:19:44.796: E/SurfaceHolder(9731): Exception locking surface
01-17 00:19:44.796: E/SurfaceHolder(9731): java.lang.IllegalArgumentException
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.Surface.lockCanvasNative(Native Method)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.Surface.lockCanvas(Surface.java:314)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:762)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:741)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at com.frequency.FreqTapArea$2.onTouch(FreqTapArea.java:54)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.View.dispatchTouchEvent(View.java:3897)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1737)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1153)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1721)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2200)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1884)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.os.Handler.dispatchMessage(Handler.java:99)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.os.Looper.loop(Looper.java:130)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at android.app.ActivityThread.main(ActivityThread.java:3835)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at java.lang.reflect.Method.invokeNative(Native Method)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at java.lang.reflect.Method.invoke(Method.java:507)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
01-17 00:19:44.796: E/SurfaceHolder(9731):  at dalvik.system.NativeStart.main(Native Method)

我们将不胜感激。

【问题讨论】:

  • 你能发布你得到的错误吗?我只是在模拟器中运行了您的代码而没有问题。或者也许在您尝试实例化自定义 SurfaceView 的地方发布代码/XML?还应注意,您的 Log 语句放错了位置;无论抽奖是否成功,它都会被调用。
  • 嘿,我已经删除了 try/finally 块并且错误仍然存​​在并且它没有在表面上绘制任何东西。我已经更新了代码并添加了错误日志。
  • 您新发布的代码在绘制后无法解锁画布(mSurfaceHolder.unlockCanvasAndPost(c) 消失了)。此外,mHandler 从未在任何地方声明。

标签: java android android-layout


【解决方案1】:

您需要在画布上绘图后解锁。 正确的顺序是:

  1. 调用 mSurfaceHolder.lockCanvas() 获取画布;
  2. 在画布上绘图。
  3. 调用 mSurfaceHolder.unlockCanvasAndPost(c) 解锁画布;

在您的代码中可能是:

public boolean onTouch(View arg0, MotionEvent arg1) {
        if (!mLoaded)
            return false;

        Canvas c = mSurfaceHolder.lockCanvas();
        drawTap(c, arg1);
        mSurfaceHolder.unlockCanvasAndPost(c);

        return true;
    }

【讨论】:

  • 我的旧代码有类似的东西(应该保留在 OP 中),除了 lockCanvas()try 块中,unlockCanvasAndPost(c)finally 块中。我会试一试这段代码,然后回复你。
猜你喜欢
  • 1970-01-01
  • 2014-09-18
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多