• 写在前面          

  最近忙着赶项目进度,都不知道这次博客写点啥好了,前两天碰巧遇到一个奇怪的bug,项目中未发现与异常相关的类,于是去百度、谷歌搜索,发现这是一个早就可能被写烂吐槽的RecyclerView的bug.

  • 透过现象看本质

  不知道你们遇见没有,在RecyclerView被推的如火如荼的时候,你喜欢它,你默默用它,青睐于它的健壮性。你觉得,这玩意儿都出来这么久了,一定没问题。然而,在某一次快速滑动中,Boom,崩溃了!

  先来看下logcat打的崩溃日志:


 1 java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).
2 at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3300)
3 at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3258)
4 at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1803)
5 at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1302)
6 at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1265)
7 at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1093)
8 at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:956)
9 at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:2715)
10 at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
11 at android.view.Choreographer.doCallbacks(Choreographer.java:555)
12 at android.view.Choreographer.doFrame(Choreographer.java:524)
13 at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
14 at android.os.Handler.handleCallback(Handler.java:615)
15 at android.os.Handler.dispatchMessage(Handler.java:92)
16 at android.os.Looper.loop(Looper.java:137)
17 at android.app.ActivityThread.main(ActivityThread.java:4921)
18 at java.lang.reflect.Method.invokeNative(Native Method)
19 at java.lang.reflect.Method.invoke(Method.java:511)
20 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
21 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
22 at dalvik.system.NativeStart.main(Native Method)

  数组越界?这日志看上去根本就跟我们代码无关呀。多番Google发现,这貌似是Google程序员的锅?内部bug?这TM官方的问题,关你何事?要不不用RecyclerView了吧?

你是一个优秀的程序猿,不应该总是逃避问题,而应该思考如何去解决它。不过这说明了一个问题,人非圣贤孰能无过,连Google程序员那么牛逼的存在都会出问题。

崩溃的原因比较清楚,如果绑定的集合List中的数据和RecycerView的数据不一致的时候,调用更新方法的时候会复现。

  • 临时解决办法

    有人这么说,造成崩溃的原因极有可能是当clear了之后,迅速上滑,但由于新数据还没来,导致RecyclerView需要更新加载下面的Item的时候,找不到数据源,导致了崩溃的发生。

所以,既然如此,一定可以通过让Clear的时候,禁止RecyclerView的滑动来解决它。代码如下:

 1 private boolean mIsRefreshing=false;
2 mRecyclerView.setOnTouchListener(
3 new View.OnTouchListener() {
4 @Override
5 public boolean onTouch(View v, MotionEvent event) {
6 if (mIsRefreshing) {
7 return true;
8 } else {
9 return false;
10 }
11 }
12 }
13 );
14 //当刷新时设置
15 //mIsRefreshing=true;
16 //刷新完毕后还原为false
17 //mIsRefreshing=false;
  • 别人怎么说

人,想法,总是千奇百怪。

造成崩溃的原因其实很明显,如果你更新集合List后,调用RVAdapter的notifyXXXX方法时,adapter的更新预期接口和实际集合更新结果不同,就会出现这个异常!不信你可以随便模拟这个情况的发生。

所以有人就得到了这样的结论:

1、RVAdapter的notifyDataSetChanged方法执行后,在一定时间内,如果你更新了你的集合(无论是否在主线程更新集合),那么这个更新会实时反应到控件上,也就是说你的控件显示也会更新。

2、调用诸如notifyItemRangeInserted这样的方法之前,考虑清楚你的集合到底更新成什么样了!要注意参考结论1,结论1会影响你的判断。

  • 靠谱的解决办法

显然,上面的方法都不太好用,继续研究发现,直接采用下面的方法可以很好的解决。

经过多番研究发现,直接像下面这样,可以完美解决我们的问题。

  保证Adapter内的list和获取到的数据list不是同一个list就好.

 Class MyAdapter extends RecyclerView.Adapter{
private List<Object>mList;
... public void notifySetListDataChanged(List<Object>list){
this.mList = list;
notifySetDataChanged();
}
}

每次数据更新(只要有变动都认为是更新)都调用

adapter.notifySetListDataChanged(list);这里的list是变动更新后的数据list;

  • 写在最后

细心和耐心在编程之路显得尤为重要,只有抱着对bug0容忍的态度和决心,我们才能越过高山,发现更高更远的天空

												

偶遇RecyclerView内部Bug的更多相关文章

  1. 【知识整理】惊现RecyclerView内部Bug???别急,我们慢慢解决它~

    一.写在前面 这也是久违的一整个月没有写Blog,也是由于近期给妹纸找工作,各种坑蒙拐骗,然而都没卵用.额,广大朋友们,成都需要软件测试.线上运维.产品助理的伙伴,赶紧私聊我了.这妹纸,学习能力挺好, ...

  2. RecyclerView 和 ListView 使用对比分析

    原文地址:http://blog.coderclock.com/2016/08/08/android/RecyclerView%20%E5%92%8C%20ListView%20%E4%BD%BF%E ...

  3. Android RecyclerView与ListView比较

    RecyclerView 概述 RecyclerView 集成自 ViewGroup .RecyclerView是Android-support-V7版本中新增的一个Widgets,官方对于它的介绍是 ...

  4. 为RecyclerView的不同item项实现不同的布局(添加分类Header)

    最近在做一个应用的时候,需要为GridLayoutManager添加头部header,然后自然而然就想到了用不同的itemType去加载不同的布局. 1.实现多item布局,用不同的itemType去 ...

  5. 似曾相识的 RecyclerView

    一.常用方法 RecyclerView 与 ListView.GridView 类似,都是可以显示同一种类型 View 的集合的控件. 首先看看最简单的用法,四步走: ①接入 build.gradle ...

  6. RecyclerView全面解析

    写在前面 起深入浅出这名字的时候我是慎重又慎重的,生怕被人骂标题党,写的什么破玩意还敢说深入浅出.所以还是请大家不要抱着太高的期望,因为没有期望就没有失望,就像陈润说的,超预期嘛.全当看小说的心情来看 ...

  7. 【Android - MD】之RecyclerView的使用

    RecyclerView是Android 5.0新特性--Material Design中的一个控件,它将ListView.GridView整合到一起,可以使用极少的代码在ListView.GridV ...

  8. 项目管理实践【四】Bug跟踪管理【Bug Trace and Management】

    首先,向大家说一声抱歉,这篇文章耽误了这么久才和大家见面.至于Bug的跟踪和管理的必要性和好处,我就不在这里说了,下面介绍几款Bug跟踪和管理的软件. 一.BugNET BugNET是一个非常优秀的开 ...

  9. 关于RecyclerView你知道的不知道的都在这了(下)

    目录 目录 正文 6. Recycler 7. ItemAnimator 8. ItemDecoration 9. OnFlingListener 目录 由于本篇篇幅特长,特意做了个目录,让大伙对本篇 ...

随机推荐

  1. 转:windbg调试堆

    转:http://www.cnblogs.com/dsky/archive/2013/05/15/3079363.html 简评: 代码中采用malloc/free进行堆申请,实际调用的仍然是Heap ...

  2. 货币金额javascript正则表达式

    最多保留两位小数,货币金额(不能为0): /^(([1-9]\d*)(\.\d{1,2})?)$|^(0\.0?([1-9]\d?))$/

  3. Web框架以及两种模式MVC,MTV

    一.Web框架的本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. import socket def handle_reques ...

  4. Java 获取JVM内存和物理内存信息

    package com.sysinfo; public class MonitorInfo { /** jvm可使用内存. */ private long totalMemory; /** jvm剩余 ...

  5. 【欧拉回路】Play On Words(6-16)

    [UVA10129]Play On Words 算法入门经典第6章6-16(P169) 题目大意:有一些单词,问能不能将它们串成字符串(只有前缀和后缀相同才能连) 试题分析:很巧妙的一道题,将每个单词 ...

  6. 【动态规划】CDOJ1692 这是一道比CCCC简单题更有想象力的中档题

    f(i,j)表示打了i行出现j个bug的方案数. 还是跟背包有点像嘛. #include<cstdio> using namespace std; int n,m,b,mod,a[510] ...

  7. 【单调队列DP+manacher】BZOJ2565-最长双回文串

    [题目大意] 输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串. [思路] 首先普通地求manacher,然后求出以每个位置为左端点和右端 ...

  8. 20162304 实验二《Java面向对象程序设计》实验报告

    20162304 实验二<Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 ...

  9. MySQL v5.7.18 版本解压安装

    下载MySQL https://dev.mysql.com/downloads/mysql/5.1.html#downloads 个人机子是64位的,所以选择下载:Windows (x86, 64-b ...

  10. [转]iBatis简单入门教程

    iBatis 简介: iBatis 是apache 的一个开源项目,一个O/R Mapping 解决方案,iBatis 最大的特点就是小巧,上手很快.如果不需要太多复杂的功能,iBatis 是能够满足 ...