Android Canvas锁定抛出IllegalArgumentException

我正在尝试实现我自己的自定义SurfaceView,当触摸时,在用户触摸屏幕的位置绘制一个圆圈。 但是,当我调用mSurfaceHolder.lockCanvas()我得到一个exception。 每当canvas锁定时,就会出现非法参数。 示例代码发布在下面。

 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) 

非常感谢帮助。

绘图后需要解锁canvas。 正确的保证是:

  1. get de canvas调用mSurfaceHolder.lockCanvas();
  2. 在canvas上画画。
  3. 解锁canvas调用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; }