IllegalArgumentException:指针索引超出SwipeRefreshLayout的范围 [英] IllegalArgumentException: pointerIndex out of range from SwipeRefreshLayout

查看:166
本文介绍了IllegalArgumentException:指针索引超出SwipeRefreshLayout的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在crashlytics上遇到了一些IllegalArgumentException: pointerIndex out of range崩溃,我不知道发生了什么.它不仅限于一个Android版本或设备,它发生在5.0.1、4.4.4、4.4.2、4.0.4、2.3.6的所有设备上.以下是完整的日志输出,以获取更多上下文.

I've been getting some of these IllegalArgumentException: pointerIndex out of range crashes on crashlytics and I don't understand what's happening. It's not limited to one android build or device, it happens on 5.0.1, 4.4.4, 4.4.2, 4.0.4, 2.3.6 all on various devices. Below is the full log output for more context.

java.lang.RuntimeException: Unable to destroy activity {com.mypackage.myapp/com.mypackage.myapp.MyListActivity}: java.lang.IllegalArgumentException: pointerIndex out of range
       at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3671)
       at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3689)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3889)
       at android.app.ActivityThread.access$900(ActivityThread.java:144)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5221)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
Caused by: java.lang.IllegalArgumentException: pointerIndex out of range
       at android.view.MotionEvent.nativeGetAxisValue(MotionEvent.java)
       at android.view.MotionEvent.getY(MotionEvent.java:1998)
       at android.support.v4.view.MotionEventCompatEclair.getY(MotionEventCompatEclair.java:35)
       at android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.getY(MotionEventCompat.java:95)
       at android.support.v4.view.MotionEventCompat.getY(MotionEventCompat.java:228)
       at android.support.v4.widget.SwipeRefreshLayout.onTouchEvent(SwipeRefreshLayout.java:772)
       at android.view.View.dispatchTouchEvent(View.java:8388)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2398)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2158)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2400)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
       at android.view.ViewGroup.cancelTouchTarget(ViewGroup.java:2340)
       at android.view.ViewGroup.removeViewInternal(ViewGroup.java:4156)
       at android.view.ViewGroup.removeViewInternal(ViewGroup.java:4136)
       at android.view.ViewGroup.removeView(ViewGroup.java:4068)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1045)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
       at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1954)
       at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:313)
       at android.support.v7.app.ActionBarActivity.onDestroy(ActionBarActivity.java:169)
       at com.mypackage.myapp.BaseActivity.onDestroy(BaseActivity.java:105)
       at android.app.Activity.performDestroy(Activity.java:6112)
       at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1140)
       at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3658)
       at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3689)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3889)
       at android.app.ActivityThread.access$900(ActivityThread.java:144)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5221)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

这是来自android.view.MotionEvent.getY()的另一个相关的崩溃报告.

Here is another related crash report coming from android.view.MotionEvent.getY().

java.lang.RuntimeException: Unable to destroy activity {com.mypackage.myapp/com.mypackage.myapp.MyListActivity}: java.lang.ArrayIndexOutOfBoundsException
       at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:2683)
       at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:2701)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2817)
       at android.app.ActivityThread.access$1600(ActivityThread.java:117)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:946)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:130)
       at android.app.ActivityThread.main(ActivityThread.java:3733)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:507)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:931)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.ArrayIndexOutOfBoundsException
       at android.view.MotionEvent.getY(MotionEvent.java:903)
       at android.support.v4.view.MotionEventCompatEclair.d(MotionEventCompatEclair.java:35)
       at android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.d(MotionEventCompat.java:95)
       at android.support.v4.view.MotionEventCompat.d(MotionEventCompat.java:228)
       at android.support.v4.widget.SwipeRefreshLayout.onTouchEvent(SwipeRefreshLayout.java:772)
       at android.view.View.dispatchTouchEvent(View.java:3971)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)
       at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1154)
       at android.view.ViewGroup.removeViewInternal(ViewGroup.java:2201)
       at android.view.ViewGroup.removeViewInternal(ViewGroup.java:2187)
       at android.view.ViewGroup.removeView(ViewGroup.java:2135)
       at android.support.v4.app.FragmentManagerImpl.a(FragmentManager.java:1045)
       at android.support.v4.app.FragmentManagerImpl.a(FragmentManager.java:1126)
       at android.support.v4.app.FragmentManagerImpl.a(FragmentManager.java:1108)
       at android.support.v4.app.FragmentManagerImpl.t(FragmentManager.java:1954)
       at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:313)
       at android.support.v7.app.ActionBarActivity.onDestroy(ActionBarActivity.java:169)
       at com.mypackage.myapp.BaseActivity.onDestroy(BaseActivity.java:105)
       at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:2670)
       at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:2701)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2817)
       at android.app.ActivityThread.access$1600(ActivityThread.java:117)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:946)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:130)
       at android.app.ActivityThread.main(ActivityThread.java:3733)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:507)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:931)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689)
       at dalvik.system.NativeStart.main(NativeStart.java)

所以我的问题是什么导致了此错误,缓解该问题的可接受方法是什么?

So my question is what is causing this error and what would be the acceptable method for mitigating this issue?

这是指向 MotionEvent.java:1998 ,在上面的崩溃中被引用.

Here is the link to MotionEvent.java:1998 which is referenced in the crash above.

这是我的onDestroy样子:

Here is my onDestroy looks like:

@Override
public void onDestroy() {

    AppMsg.cancelAll();
    SuperCardToast.cancelAllSuperCardToasts();

    super.onDestroy();
}

特别是BaseActivity.java:105是我叫super.onDestroy();的地方.

推荐答案

我假设在仍然发生触摸事件时引发了异常(在Activity即将onDestroy()时向下流到本机触摸.可以为了避免崩溃而通过捕获异常来减轻这种情况.如果活动进入此状态,它将被销毁.

I assume that exception is thrown while there is touch event still occurring (streamed down to the native touch while the Activity is about to onDestroy(). It is ok to mitigate this by catching the exception for the sake of avoiding crash. Activity is about to be destroyed if it has enter this state.

我不确定(已通过测试),但是如果捕获的异常不适合您,则可以尝试阻止任何事件完全传递给实现.

I'm not sure (havent tested), but you could try to prevent any events to be passed to implementation at all, if catching exception does not fit you.

public class ComeUpWithBetterNameSwipeRefreshLayout extends SwipeRefreshLayout {

    private boolean mAcceptEvents;

    public ComeUpWithBetterNameSwipeRefreshLayout(Context context) {
        super(context);
    }

    public void setAcceptEvents(boolean mAcceptEvents) {
        this.mAcceptEvents = mAcceptEvents;
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mAcceptEvents? super.onInterceptTouchEvent(ev) : true;
    }

    public ComeUpWithBetterNameSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mAcceptEvents = true;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mAcceptEvents = false;
    }
}

@Override
public void onDestroy() {
    mSwipeRefreshLayout.setAcceptEvents(false);
    AppMsg.cancelAll();
    SuperCardToast.cancelAllSuperCardToasts();

    super.onDestroy();
}

参加2 :

SwipeRefreshLayout尝试从无效的指针索引获取getY(),如果找不到则调用findPointerIndex(ev, activePointer)返回-1.防止调度无效指针小于0并且指针索引大于或等于该事件的指针计数的调度触摸事件,可能会阻止

SwipeRefreshLayout tries to getY() from invalid pointer index, calling findPointerIndex(ev, activePointer) returns -1 if it fails to find. Preventing dispatching touch event with invalid pointer less than 0 and pointer index greater or equal than pointer count for that event will probably prevent validation of pointer inside native MotionEvent implementation from throwing IAE.

 @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if(ev.getAction() == MotionEvent.ACTION_CANCEL) {
        int pointerCount = MotionEventCompat.getPointerCount(ev);
        int index = MotionEventCompat.getActionIndex(ev);
        mActivePointerId = MotionEventCompat.getPointerId(ev, index);
        index = MotionEventCompat.findPointerIndex(ev,mActivePointerId);
        if (index > -1 && index < pointerCount) {
            super.onInterceptTouchEvent(ev);
        } else {
            return true;
        }
    }else if(ev.getAction() == MotionEventCompat.ACTION_POINTER_DOWN && super.onInterceptTouchEvent(ev)) {
        final int index = MotionEventCompat.getActionIndex(ev);
        mActivePointerId = MotionEventCompat.getPointerId(ev, index);
        return false;
    }else if(ev.getAction() == MotionEventCompat.ACTION_POINTER_UP && super.onInterceptTouchEvent(ev)){
        onSecondaryPointerUp(ev);
        return false;
    }else if(ev.getAction() == MotionEvent.ACTION_DOWN && super.onInterceptTouchEvent(ev)){
        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        return false;
    }
    return super.onInterceptTouchEvent(ev);
}

private void onSecondaryPointerUp(MotionEvent ev) {
    final int pointerIndex = MotionEventCompat.getActionIndex(ev);
    final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
    if (pointerId == mActivePointerId) {
        final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
        mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
    }
}

这篇关于IllegalArgumentException:指针索引超出SwipeRefreshLayout的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆