2012-01-16 28 views
10

Dokunduğunda, kullanıcının ekrana dokunduğu noktada çember çizen kendi özel SurfaceView'ımı uygulamaya çalışıyorum. Ancak, mSurfaceHolder.lockCanvas()'u aradığımda bir istisna alıyorum. Kanvas kilitlendiğinde yasadışı bir argümanın çizgileri boyunca bir şey. Örnek kod aşağıda yer almaktadır.Android Kanvas kilitleme özelliği IllegalArgumentException

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) 

Yardım büyük takdir:

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 

    } 
} 

Aşağıda ben almaya devam hata kayıtları.

+0

Eğer alıyorsanız hata gönderebilir miyim? Kodunuzu yalnızca bir emülatörde yayınlamadan çalıştırdım. Ya da belki de özel SurfaceView'ı başlatmaya çalıştığınız kodu/XML'yi postalayın. Ayrıca, Log ifadenizin yanlış yerleştirildiğine dikkat edilmelidir; çekilişin başarılı olup olmadığına bakılmaksızın her zaman çağrılır. – Devunwired

+0

Hey, try/finally bloklarını kaldırdım ve hata hala devam ediyor ve yüzeyde hiçbir şey çizmiyor. Kodu güncelledim ve hata günlüğünü ekledim. – Dan

+1

Yeni posta kodunuz çizildikten sonra tuvalin kilidini açmaz ('mSurfaceHolder.unlockCanvasAndPost (c)' kayboldu). Ayrıca, 'mHandler' hiçbir yerde beyan edilmez. – Devunwired

cevap

9

Üzerine çizdikten sonra tuvalin kilidini açmanız gerekir. doğru secuence geçerli:

  1. olsun de tuval) (mSurfaceHolder.lockCanvas çağırarak;
  2. Tuval üzerine çizim yapın.
  3. Tuval aramayı açma mSurfaceHolder.unlockCanvasAndPost (c); Kodunuzda

olabilir:

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

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

     return true; 
    } 
+1

Eski kodumda böyle bir şey vardı (OP'de tutmuş olmalıydı), 'lockCanvas()' 'try' bloğunda ve' unlockCanvasAndPost (c) '' n'' bloğunda. Bu kodu bir atış yapacağım ve size geri döneceğim. – Dan

İlgili konular