IllegalArgumentException:指针索引超出SwipeRefreshLayout的范围 [英] IllegalArgumentException: pointerIndex out of range from 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屋!