文章

Android 多点触控错误处理(java.lang.IllegalArgumentException: pointerIndex out of range)

最近做View的多点触控时,每次第一次触控事件完美运行,第二次就直接崩了,错误信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
01-03 00:05:44.220 4377-4410/system_process E/AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: android.ui
    java.lang.IllegalArgumentException: pointerIndex out of range
        at android.view.MotionEvent.nativeGetAxisValue(Native Method)
        at android.view.MotionEvent.getX(MotionEvent.java:2072)
        at com.android.server.policy.EnableAccessibilityController.onTouchEvent(EnableAccessibilityController.java:193)
        at com.android.server.policy.GlobalActions.onTouch(GlobalActions.java:1077)
        at android.view.View.dispatchTouchEvent(View.java:9404)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2660)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2304)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2666)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2666)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2666)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2666)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2666)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2666)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2447)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1766)
        at android.app.Dialog.dispatchTouchEvent(Dialog.java:797)
        at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2408)
        at android.view.View.dispatchPointerEvent(View.java:9646)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4738)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4596)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4101)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4154)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4120)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4266)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4128)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4323)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4101)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4154)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4120)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4128)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4101)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6555)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6529)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6472)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6727)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
        at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
        at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
        at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6686)
        at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6753)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:894)
        at android.view.Choreographer.doCallbacks(Choreographer.java:696)
        at android.view.Choreographer.doFrame(Choreographer.java:625)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:880)
        at android.os.Handler.handleCallback(Handler.java:815)
        at android.os.Handler.dispatchMessage(Handler.java:104)
        at android.os.Looper

解决方案:

这个bug是Android系统原因 所以第一种方式是: 修改frameworks\base\core\jni\android_view_MotionEvent.cppandroid_view_MotionEvent_nativeGetAxisValue方法 注释掉

1
2
[java]
if (!validatePointerIndex(env, pointerIndex, pointerCount)) {return 0;} 

改完后需重新编译整个系统,然后替换lib库,重新编译整个系统,这个方法就比较麻烦了。

第二种方法是:捕获IllegalArgumentException(非法参数异常)异常 即如

1
2
3
4
5
6
7
8
9
[java] 
private float spacing(MotionEvent event) { 
        try { 
        x = event.getX(0) - event.getX(1); 
        y = event.getY(0) - event.getY(1); 
    } catch (IllegalArgumentException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    } 

第二种方法简单有效。

文章可转载,转载请务必注明出处。