Support v-7 recycler view 出现IndexOutOfBoundsException: Inconsistency detected.异常解决办法。

QA提Bug说某个列表上下滑动会崩溃(非必现)。哎…,最怕的就是这种难以复现的问题了。


问题产生的原因是使用了support-v7 的RecyclerView,在刷新数据的时候会出现以下异常:

java.lang.NullPointerException
at com.rcplatform.livechat.im.SinchIMService$b.a(SinchIMService.java:592)
at com.rcplatform.livechat.ui.MainActivity.a(MainActivity.java:794)
at com.rcplatform.livechat.ui.IMServiceActivity$1.onServiceConnected(IMServiceActivity.java:26)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1113)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1130)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5232)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:746)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{418cb040 position=10 id=-1, oldPos=-1, pLpos:-1 no parent}
at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:4801)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4932)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4913)
at android.support.v7.widget.LinearLayoutManager$b.a(LinearLayoutManager.java:2029)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1193)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1043)
at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1552)
at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2649)
at android.view.View.dispatchTouchEvent(View.java:7566)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2205)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1940)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at com.rcplatform.livechat.widgets.ItemVisiableViewPager.dispatchTouchEvent(ItemVisiableViewPager.java:52)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1973)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1425)
at android.app.Activity.dispatchTouchEvent(Activity.java:2424)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:67)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1921)
at android.view.View.dispatchPointerEvent(View.java:7746)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3899)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3794)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3389)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3439)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3408)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3493)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3416)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3550)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3389)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3439)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3408)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3416)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3389)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5436)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5416)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5387)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5510)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:132)
at android.os.Looper.loop(Looper.java:124)
at android.app.ActivityThread.main(ActivityThread.java:5232)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:746)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)

从日志可以看到,这个崩溃发生在 底层。比较合适的办法是把LinearLayoutManager的onLayoutChildren方法的异常捕获。

1、创建一个类LinearLayoutManagerWrapper继承LinearLayoutManager,重写onLayoutChildren方法

    public class WrapContentLinearLayoutManager extends LinearLayoutManager {
        public WrapContentLinearLayoutManager(Context context) {
            super(context);
        }

        public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
            super(context, orientation, reverseLayout);
        }

        public WrapContentLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }

        @Override
        public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
            try {
                super.onLayoutChildren(recycler, state);
            } catch (IndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
    }

然后设置RecyclerView的LayoutManager:

recyclerView.setLayoutManager(new WrapContentLinearLayoutManager(getContext()));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值