关于RecyclerView Bug: Inconsistency detected. Invalid view holder adapter的解决方案

1、Crash异常信息

最近在公司项目中开始使用RecycleView,报了一个Crash:

关于RecyclerView Bug: Inconsistency detected. Invalid view holder adapter的解决方案_第1张图片
Inconsistency detected异常.png

2、原因分析

我的项目中遇到的问题是,在下载管理器的下载中tab里,当某个应用下载完毕时,从下载列表中remove移除这个item,会报Inconsistency detected的错误而导致程序崩溃。
" Inconsistency detected. Invalid view holder adapter"的大概意思就是 数据不一致,无效的视图适配器。
以下是项目中导致crash的方法:

public void removeData(T data) {
   if (data != null) {
      int position = getItemPosition(data);
      if(position!=-1){
         this.mDatas.remove(position);
      }
   }
}

mDatas是数据源 ArrayList,推测:数据源的这条数据被移除了,但是并没有刷新 Apdater视图,所以导致崩溃?

3、解决方案

3.1 notifyItemRemoved(position)

于是在移除item的时候加上刷新Recycleview Adapter的一行代码notifyItemRemoved(position);

public void removeData(T data) {
   if (data != null) {
      int position = getItemPosition(data);
      if(position!=-1){
         this.mDatas.remove(position);
         notifyItemRemoved(position);//如果少了这一句,会报Inconsistency detected异常而崩溃
      }
   }
}

运行程序,尝试复现问题,果然发现正常了。
所以,在进行数据移除时,务必要保证RecyclerView.Adapter中的数据和移除的数据源保持一致!

3.2 直接捕获这个异常

  • 创建一个类WrapContentGridLayoutManager继承GridLayoutManager,重写onLayoutChildren方法
 *
 * 为了解决RecyclerView的官方bug:Inconsistency detected. Invalid view holder adapter
 */
public class WrapContentGridLayoutManager extends GridLayoutManager {

    public WrapContentGridLayoutManager(Context context, int spanCount) {
        super(context, spanCount);
    }

    @Override
   public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        try {
            super.onLayoutChildren(recycler, state);
        }catch (IndexOutOfBoundsException e){
            //手动catch住
            e.printStackTrace();
            DebugLog.d("WrapContentGridLayoutManager","手动捕获异常:"+e.getMessage());
        }
    }
}
  • 设置RecyclerView的布局管理为WrapContentGridLayoutManager对象
   rv = (RecyclerView) view.findViewById(R.id.app_recycler_view);
   rv.setLayoutManager(new WrapContentGridLayoutManager(mContext,6));

其实手动捕获catch住这个异常 并不是什么好的解决方法,但是我更新到最新的V7包下RecyclerView控件,发现官方也还是没有修复这个bug,所以也只能暂时这么处理了。

4、参考

https://code.google.com/p/android/issues/detail?id=77846(google官方group讨论组里有提到)

http://stackoverflow.com/questions/31759171/recyclerview-and-java-lang-indexoutofboundsexception-inconsistency-detected-in

你可能感兴趣的:(关于RecyclerView Bug: Inconsistency detected. Invalid view holder adapter的解决方案)