安卓学习笔记---解决java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 2

最近在线上发现了一个问题,但是并没有出现错误的具体位置,错误是这样的:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 2(offset:2).state:11at 

android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5512)

at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:285)

at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:342)

at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:358)

at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:365)

at android.support.v7.widget.GapWorker.run(GapWorker.java:396)

at android.os.Handler.handleCallback(Handler.java:739)

at android.os.Handler.dispatchMessage(Handler.java:95)

at android.os.Looper.loop(Looper.java:135)at android.app.ActivityThread.main(ActivityThread.java:5446)

at java.lang.reflect.Method.invoke(Native Method)at java.lang.reflect.Method.invoke(Method.java:372)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:736)

看着像是RecyclerView的问题,但是也没报具体错误职位,不太懂这是什么意思,于是就上网百度了一下说这是RecycleView内部错误

RecyclerView 存在的一个明显的 bug 一直没有修复:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position…

重现的方法是:使用 RecyclerView 加官方下拉刷新的时候,如果绑定的 List 对象在更新数据之前进行了 clear,而这时用户紧接着迅速上滑 RV,就会造成崩溃,而且异常不会报到你的代码上,属于RV内部错误。初次猜测是,当你 clear 了 list 之后,这时迅速上滑,而新数据还没到来,导致 RV 要更新加载下面的 Item 时候,找不到数据源了,造成 crash.

在网上看到的解决方法有两个:

1.

就是在刷新,Recyclerview  clear的同时让Recyclerview不能滑动,这样的解决办法也是可以的,可以避免错误的发生,但是我总感觉这样的会影响用户的体验,该解决办法的代码如下:

mRecyclerView.setOnTouchListener(
         new  View.OnTouchListener() {
             @Override
             public  boolean  onTouch(View v, MotionEvent event) {
                 if  (mIsRefreshing) {
                     return  true ;
                 } else  {
                     return  false ;
                 }
             }
         }
);

然后去改变和恢复 mIsRefreshing 这个 boolean 即可。

2.

我们写一个MyLinearLayoutManager去继承LinearLayoutManager,在出现问题的时候我们catch了,这样的处理方法我觉得还是可以的,具体实现如下:

public class MyLinearLayoutManager extends LinearLayoutManager {  
    public MyLinearLayoutManager(Context context) {  
        super(context);  
    }  
  
    public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {  
        super(context, orientation, reverseLayout);  
    }  
  
    public MyLinearLayoutManager(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的Manager为我们自己的Manager:

mRecyclerView.setLayoutManager(new MyLinearLayoutManager(this)); 
我是使用的第二种方式,如果还有别的方式也请告知一下,这里记录一下,日后也会用到,感谢那些无私奉献的人。
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值