这段代码
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
:
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)
这似乎是不可能的,因为getPointerId
有记录从 0 获取索引getPointerCount()-1
(请参阅文档)。
我知道做的唯一奇怪的事情是我GLSurfaceView.queueEvent
用来传递MotionEvent
到 GL 表面的渲染线程进行处理:
public boolean onTouchEvent(final MotionEvent event)
{
queueEvent(new Runnable() {
public void run() {
worker.handleTouchEvent(event);
}
});
return true;
}
我正在获得对我认为应该是不可变的对象的引用,并且我认为我正在安全地将其传递给另一个线程进行处理,在那里我只进行只读访问。
因此,我将访问实际 MotionEvent 对象的代码移至 UI 线程,但由于该问题很少发生,因此在应用程序发布之前我不知道我是否真正解决了该问题。
问题:这里真正出了什么问题?
后续问题:假设这与我使用多线程有关,我如何安全地将 MotionEvent 发送到另一个线程?