2012-01-16 34 views
10

タッチしたときにユーザーが画面に触れた場所にサーフェイスを描画する独自のカスタムSurfaceViewを実装しようとしています。しかし、私がmSurfaceHolder.lockCanvas()と呼ぶとき、私は例外を得る。キャンバスがロックするたびに、違法な引数の行に沿って何かがあります。サンプルコードは以下に掲載されています。以下はAndroid CanvasのロックでIllegalArgumentExceptionがスローされる

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) 

ヘルプをいただければ幸いです。

+0

あなたが取得しているエラーを投稿することができますか?エミュレータで問題なくコードを実行しました。あるいはカスタムSurfaceViewのインスタンスを作成しようとしているところでコード/ XMLを投稿するのでしょうか?また、Logステートメントが間違っていることにも注意してください。引き分けが成功したかどうかにかかわらず、常に呼び出されます。 – Devunwired

+0

ねえ、try/finallyブロックを削除しましたが、エラーはそのまま残り、表面には何も描画されません。私はコードを更新し、エラーログを追加しました。 – Dan

+1

新たに投稿されたコードは、描画後にキャンバスのロックを解除しません( 'mSurfaceHolder.unlockCanvasAndPost(c)'が消えました)。また、 'mHandler'はどこにも決して宣言されません。 – Devunwired

答えて

9

キャンバスを描画した後にロックを解除する必要があります。 右のセキュリティは:

  1. get canvas 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; 
    } 
+1

私の古いコードは 'lockCanvas()'が 'try'ブロックにあり、' unlockCanvasAndPost(c) 'が' finally'ブロックにある点を除いて、OPの中にそれを保持していたはずのものです。私はこのコードにショットをつけて、あなたに戻ってきます。 – Dan

関連する問題