Android知识总结:ListView 出现IndexOutOfBoundsException异常

背景

今天在整理友盟统计bug时,发现有几个bug集中在首页ListView的Adapter上,具体翻来,大概是说ListView中数据出现越界。具体错误日志大概如下:
java.lang.IndexOutOfBoundsException: Invalid index 4, size is 0
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
    at java.util.ArrayList.get(ArrayList.java:304)
    ... ...

也就是说,我们的ListView中的数据列表长度为0,但是我们索引到了index为4的数据。卧槽,ListView数组的内容不是由Adapter管理的吗,为什么此处会产生越界?

翻阅了一些网页,大家都提到ListView是异步的,也有些说法是不要使用Adapter的notifyDataSetChanged方法,我也开始怀疑是不是notifyDataSetChanged方法使用的不对。总之,想要复现这个bug似乎并不是很容易。

既然复现不了,那么我们就再捋一下代码,看看能不能找到什么线索,代码中请求数据和刷新数据的流程大概如下:

mDataList.clear();//清空列表

final GsonRequest<HomeJson> request = new GsonRequest<>(url, HomeBean.class, psd,
       new Response.Listener<HomeBean>() {
       @Override
       public void onResponse(HomeJson response) {
       if (请求数据成功) {
               //更新数据列表               
               mDataList = response.getData();
               //进行notifyDataSetChanged
               showView(); 
               ... ...

我们的流程是,先清空列表,然后进行网络加载,当加载成功后将数据赋值给Adapter,然后notifyDataSetChanged。那么,请求网络过程中呢…… 当然还显示页面上的ListView了,那么,当请求网络的过程中有人滚动屏幕呢,我们ListView中的数据已经清空,那么Adapter的getView中将无法拿到要显示的数据。这样,就出现了数组长度为0,但是索引index为大于0的数字的情况。

这也正是体现了ListView的异步,虽然数据变化了,但是ListView本身并不知道,所以我们需要及时调用notifyDataSetChanged,告诉ListView数据变化啦,你显示的时候要用新数据了。

我们可以进行如下修改:

... ... 
mDataList.clear();
//更新数据列表               
mDataList = response.getData();
//进行notifyDataSetChanged
showView(); 
... ...

我们在网络请求完毕后删除List的数据,然后直接进行notifyDataSetChanged,这样始终保持ListView与数据列表是同步的,就不会出现数据列表与index不同步而出现IndexOutOfBoundsException的问题了。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值