0

SurfaceView을 사용하여 내 앱 오버레이로 터치를 그립니다. SurfaceView 이후MotionEvent가 아직 사용 중 재활용 됨

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

앉아 그래서 그들을 포함 ViewGroupSurfaceView과 동시에 모두 내가

MyViewGroup를 추가하는 동안은 터치 이벤트에 응답 할 수 있도록 내 다른 View들 싶습니다 다른 견해 뒤에, 이것은 위대한 작품. SurfaceView 및 그 위에있는 ViewMotionEvent을받습니다.

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; 
    } 
} 

내가 디버그 모드에서이 코드를 실행에 걸쳐 내 손가락을 때 ViewGroupx, 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. 
} 

각 이벤트는 여전히 복사이 방법 (그것에 대해 무엇을해야되지 않음)하지만 적어도 오브젝트는 재사용됩니다.