我正在尝试实现自己的自定义SurfaceView,当触摸它时,它会在用户触摸屏幕的位置绘制一个圆圈。但是,当我调用mSurfaceHolder.lockCanvas()
时,出现异常。每当 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 上绘制后,您需要将其解锁。
正确的安全性是:
在您的代码中可能是:
public boolean onTouch(View arg0, MotionEvent arg1) {
if (!mLoaded)
return false;
Canvas c = mSurfaceHolder.lockCanvas();
drawTap(c, arg1);
mSurfaceHolder.unlockCanvasAndPost(c);
return true;
}