2016-05-31 26 views
1

Ich versuche, eine Liste von Zeigern zu erhalten, ob sie unten sind, und ihre Positionen in Pixel auf dem Bildschirm, so dass ich mein Desktop-Spiel auf Android portieren kann. Um dies zu tun, habe ich dies aufTouch-Handler geschrieben.Android Multi-Touch - IllegalArgumentException in TouchMove-Ereignis

private boolean onTouch(View v, MotionEvent e) 
{ 
    final int action = e.getActionMasked(); 

    switch (action) 
    { 
     case MotionEvent.ACTION_DOWN: 
      surfaceView.queueEvent(() -> postTouchEvent(FINGER_0, true, e.getX(), e.getY())); 
      break; 

     case MotionEvent.ACTION_UP: 
      surfaceView.queueEvent(() -> postTouchEvent(FINGER_0, false, e.getX(), e.getY())); 
      break; 

     case MotionEvent.ACTION_POINTER_DOWN: 
     case MotionEvent.ACTION_POINTER_UP: 
     { 
      final int index = e.getActionIndex(); 
      final int finger = index + 1; 

      if (finger < FINGER_1 || finger > FINGER_9) 
       break; 

      final boolean isDown = action == MotionEvent.ACTION_POINTER_DOWN; 
      surfaceView.queueEvent(() -> postTouchEvent(finger, isDown, e.getX(), e.getY())); 
     } 
     break; 

     case MotionEvent.ACTION_MOVE: 
      for (int i = 0; i < e.getPointerCount(); i++) 
      { 
       final int finger = i + 1; 

       if (finger < FINGER_0 || finger > FINGER_9) 
        break; 

       surfaceView.queueEvent(() -> 
         postTouchEvent(finger, true, e.getX(finger - 1), e.getY(finger - 1))); 
      } 
      for (int i = e.getPointerCount(); i < FINGER_9; i++) 
      { 
       final int finger = i + 1; 
       surfaceView.queueEvent(() -> postTouchEvent(finger, false, 0, 0)); 
      } 
      break; 
    } 

    return true; 
} 

Das Problem jedoch mit dem ACTION_MOVE Ereignisse ist, erhalte ich die ein IllegalArgumentException für meinen Index-IDs zugreifen. Dies passiert nur, wenn ich drei oder mehr Finger gleichzeitig auf den Bildschirm tippe, aber es ist immer noch ein Problem. Die Ausnahme ist wie folgt.

FATAL EXCEPTION: GLThread 61026 
Process: com.shc.silenceengine.tests.android, PID: 23077 
java.lang.IllegalArgumentException: pointerIndex out of range 
    at android.view.MotionEvent.nativeGetAxisValue(Native Method) 
    at android.view.MotionEvent.getX(MotionEvent.java:2014) 
    at com.shc.silenceengine.backend.android.AndroidInputDevice.lambda$onTouch$14(AndroidInputDevice.java:228) 
    at com.shc.silenceengine.backend.android.AndroidInputDevice.access$lambda$6(AndroidInputDevice.java) 
    at com.shc.silenceengine.backend.android.AndroidInputDevice$$Lambda$7.run(Unknown Source) 
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462) 
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239) 

Ich bin mir nicht sicher, warum ich den Fehler bin immer, weil ich die for-Schleife mache nur bis zu e.getPointerCount() so gibt es keine Chance des Index ist aus dem Code geht.

Ich möchte nicht die Zeiger-IDs verfolgen, ich möchte nur eine rohe Liste von Zeigern und diese Ereignisse bilden in meiner Engine-Liste zum nächsten Frame.

Wer mich zeigen, wo das Problem liegt?

Antwort

1

Du e.getX() und e.getY() aus einem separaten (später) Thread ruft - ist es wahrscheinlich, dass der interne Zustand des MotionEvent Objekt zwischen dem onTouch() Rückruf und Ausführung des Threads verändert hat.

sollten Sie nur annehmen, dass die Motion Objekt während der onTouch() Methode und rufen Sie die Werte für getX() und getY() passieren auf den Faden vor das Verfahren beendet gültig ist.

+0

Genau! Danke, dass du darauf hingewiesen hast. –