Android 多点触控 - TouchMove 事件中的 IllegalArgumentException
Android multi touch - IllegalArgumentException in TouchMove event
我正在尝试获取指针列表,它们是否向下,以及它们在屏幕上的像素位置,以便我可以将我的桌面游戏移植到 android。为此,我编写了这个 onTouch 处理程序。
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;
}
然而问题出在 ACTION_MOVE
事件上,我得到一个 IllegalArgumentException
来访问我的索引 ID。只有当我同时在屏幕上点击三个或更多手指时才会发生这种情况,但这仍然是一个问题。异常情况如下
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(AndroidInputDevice.java:228)
at com.shc.silenceengine.backend.android.AndroidInputDevice.access$lambda(AndroidInputDevice.java)
at com.shc.silenceengine.backend.android.AndroidInputDevice$$Lambda.run(Unknown Source)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)
我不确定为什么会出现错误,因为我只在 e.getPointerCount()
之前执行 for 循环,因此索引不可能超出代码范围。
我不想跟踪指针 ID,我只想要一个原始的指针列表,这些事件在我的引擎列表中构成到下一帧。
有人指出问题出在哪里吗?
您正在从一个单独的(稍后的)线程调用 e.getX()
和 e.getY()
- MotionEvent
对象的内部状态可能在 onTouch()
回调和线程的执行。
您应该只假设 MotionEvent 对象在 onTouch()
方法期间有效并检索 getX()
和 getY()
的值以传递给线程 before 方法退出。
我正在尝试获取指针列表,它们是否向下,以及它们在屏幕上的像素位置,以便我可以将我的桌面游戏移植到 android。为此,我编写了这个 onTouch 处理程序。
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;
}
然而问题出在 ACTION_MOVE
事件上,我得到一个 IllegalArgumentException
来访问我的索引 ID。只有当我同时在屏幕上点击三个或更多手指时才会发生这种情况,但这仍然是一个问题。异常情况如下
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(AndroidInputDevice.java:228)
at com.shc.silenceengine.backend.android.AndroidInputDevice.access$lambda(AndroidInputDevice.java)
at com.shc.silenceengine.backend.android.AndroidInputDevice$$Lambda.run(Unknown Source)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)
我不确定为什么会出现错误,因为我只在 e.getPointerCount()
之前执行 for 循环,因此索引不可能超出代码范围。
我不想跟踪指针 ID,我只想要一个原始的指针列表,这些事件在我的引擎列表中构成到下一帧。
有人指出问题出在哪里吗?
您正在从一个单独的(稍后的)线程调用 e.getX()
和 e.getY()
- MotionEvent
对象的内部状态可能在 onTouch()
回调和线程的执行。
您应该只假设 MotionEvent 对象在 onTouch()
方法期间有效并检索 getX()
和 getY()
的值以传递给线程 before 方法退出。