2012-09-03 2 views
0

이 코드 산발적으로getPointerId는 인덱스가 범위를

android.view.MotionEvent event = ...; 

for(int i = 0, n = event.getPointerCount(); i < n; i++) 
{ 
    handleTouch(event.getPointerId(i), event.getX(i), event.getY(i)); 
} 

의 경우에도 예외를 슬로우 IllegalArgumentException 발생 :

이 아주 불가능 getPointerId으로 0 getPointerCount()-1에서 인덱스를 취할 설명되어 보인다
09-03 19:43:21.996 E/AndroidRuntime(9484): FATAL EXCEPTION: GLThread 732 
09-03 19:43:21.996 E/AndroidRuntime(9484): java.lang.IllegalArgumentException: pointerIndex out of range 
09-03 19:43:21.996 E/AndroidRuntime(9484):  at android.view.MotionEvent.nativeGetPointerId(Native Method) 
09-03 19:43:21.996 E/AndroidRuntime(9484):  at android.view.MotionEvent.getPointerId(MotionEvent.java:1927) 

(the documentation 참조). 내가 뭘 알고 있어요

유일한 이상한 것은 내가 처리를 위해 GL 표면의 렌더링 스레드에 MotionEvent을 통과 GLSurfaceView.queueEvent를 사용한다는 것입니다 :

public boolean onTouchEvent(final MotionEvent event) 
{ 
    queueEvent(new Runnable() { 
     public void run() { 
      worker.handleTouchEvent(event); 
     } 
    }); 
    return true; 
} 

내가 개체에 대한 참조를 얻고 그 I 생각은 불변이어야하고, 나는 안전하게 읽기 전용 액세스 만하고있는 처리를 위해 다른 스레드로 안전하게 전달한다고 생각합니다.

따라서 실제 MotionEvent 객체에 액세스하는 코드를 UI 스레드로 옮기고 있지만 문제가 매우 드물게 발생하기 때문에 앱이 배송 될 때까지 문제가 진정으로 해결되었는지는 알 수 없습니다.

질문 : 여기에 무슨 문제가 있습니까?

후속 질문 : 내가 안전하게 다른 스레드에 MotionEvent를 보내 어떻게,이 멀티 스레딩의 내 사용과 관련이있다 가정?

답변

0

추가 테스트 후, 지금이다 Android 프레임 워크가 onTouchEvent가 반환 된 후 실제로 MotionEvent 객체를 다시 사용한다고 확신했습니다.

따라서 이벤트 객체는 변경 불가능한 객체로 간주되어서는 안됩니다. 특히 이벤트 처리 함수의 끝 부분을 넘어서서는 안되며 다른 스레드로 전달되어야합니다.

0

은 당신이 언급 한 the documentation에 따르면, 당신이 얻기 위해서는, getX(), getY()의 호출에 findPointerIndex()에서 가져온 인덱스를 사용해야합니다

for (int i = 0, n = event.getPointerCount(); i < n; i++) 
{ 
    int pid = event.getPointerId(i); 
    int index = event.findPointerIndex(pid); 
    if (index != -1) 
    { 
     handleTouch(pid, event.getX(index), event.getY(index)); 
    } 
} 
+0

findPointerIndex는 getPointerId와 반대입니다. 따라서, event.findPointerIndex (event.getPointerId (i)) == i. – wolfgang

관련 문제