0

我使用SurfaceView來繪製觸摸作爲覆蓋我的應用程序的覆蓋。我想我的其他View s到能夠響應觸摸事件,而在同一時間作爲SurfaceView所以包含它們的ViewGroup兩個我加入MotionEvent在仍在使用時被回收

MyViewGroup:

@Override 
public boolean onInterceptTouchEvent(MotionEvent motionEvent){ 
    mSurfaceView.onTouchEvent(motionEvent); 
    return false; 
} 

由於SurfaceView坐鎮在其他觀點背後,這個作品很棒。頂部的SurfaceViewView都會收到MotionEvent

SurfaceView然後進一步將事件轉發到線程渲染進去。

MySurfaceView:

@Override 
public boolean onTouchEvent(MotionEvent motionEvent) { 
    if (mThreadHandler != null){ 
     mThreadHandler.sendMotionEvent(motionEvent); 
    } 
    return true; 
} 

然後,當我的渲染線程接收到消息它運行:

MyRenderThread:

private void handleMotionEvent(MotionEvent motionEvent){ 
    switch (motionEvent.getAction()){ 
     case MotionEvent.ACTION_DOWN: 
      float x = motionEvent.getX();       // Breakpoint 1 
      float x2 = motionEvent.getX();       // Breakpoint 2 
      float x3 = motionEvent.getX();       // Breakpoint 3 
      path.moveTo(motionEvent.getX(), motionEvent.getY()); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      path.lineTo(motionEvent.getX(),motionEvent.getY()); 
      break; 
     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_CANCEL: 
       // do nothing 
      break; 
     default: 
      break; 
    } 
} 

當我運行在調試模式下此代碼,只需滑動我的手指ViewGroup的值爲x,x2和全部不同。我懷疑這是因爲UI線程在被MyRenderThread消耗之前重新使用了MotionEvent。我怎樣才能解決這個問題?

壞的解決辦法是每個MotionEvent複製爲一個新的對象,並傳遞到MyRenderThread,但這需要對象創建/銷燬了很多

回答

0

MotionEvent.obtain(MotionEvent ev)將是輸入事件的副本池返回MotionEvent

MyViewGroup:

@Override 
public boolean onInterceptTouchEvent(MotionEvent motionEvent){ 
    mSurfaceView.fowardTouchEvent(MotionEvent.obtain(motionEvent); 
    return false; 
} 

MySurfaceView:

public void forwardTouchEvent(MotionEvent motionEvent){ 
    if (scratchpadThreadHandler != null){ 
     scratchpadThreadHandler.sendMotionEvent(motionEvent); 
    } 
} 

MyRenderThread:

private void handleMotionEvent(MotionEvent motionEvent){ 
    switch (motionEvent.getAction()){ 
     case MotionEvent.ACTION_DOWN: 
      float x = motionEvent.getX();       // Breakpoint 1 
      float x2 = motionEvent.getX();       // Breakpoint 2 
      float x3 = motionEvent.getX();       // Breakpoint 3 
      path.moveTo(motionEvent.getX(), motionEvent.getY()); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      path.lineTo(motionEvent.getX(),motionEvent.getY()); 
      break; 
     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_CANCEL: 
       // do nothing 
      break; 
     default: 
      break; 
    } 
    motionEvent.recycle(); // Mark this MotionEvent as available for recycling. 
} 

這樣,每個事件仍然複製(不知道該怎麼做的事情),但至少對象被重用。

相關問題