为什么会抛出这个异常
抛出这种异常的原因不外乎以下几种:
- 一般是在用户滑动列表时又点击刷新列表(或请求列表数据)发生此异常
- UI线程正在取adapter数据,后台线程在更新adapter数据。
一言以蔽之,adapter的数据集在外部、内部不一致时,会抛出此异常。
解决方案
对于这种情况,有一部分人是这样解决的:自己写一个继承LinearLayoutManager的包装类,在onLayoutChildren()方法里try-catch捕获该异常
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
这种方法,虽然拦截了异常,但是会使RecyclerView的数据集依然处于不一致状态,很有可能RV从那时起将继续崩溃,因为它丢失了状态。
我们的解决思路应该是如何让RV的数据集保持一致。
正确的解决办法是外部数据集发生改变时,让adapter及时做好处理。示例代码如下:
/*通知adapter,数据集发生改变*/
private void waybillListRefresh(){
int currentSize = listWaybill.size();
listWaybill.clear();
mAdapter.notifyItemRangeRemoved(0, currentSize);
//调用此方法后需要进行对后面的所有数据进行调用
//notifyItemRangeChanged(startPosition,allCount-startPosition);
//网络请求
mPageNo = 1;
getWaybillList(date);
}
/*填充数据*/
private void setData(){
if (list.size() > 0){
recycler.hideEmptyView();
listWaybill.addAll(list);
mAdapter.notifyItemRangeInserted(0, listWaybill.size());
}
}