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

来源:互联网 发布:淘宝拉夏贝尔代购 编辑:程序博客网 时间:2024/06/07 22:20

背景

今天在整理友盟统计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();//进行notifyDataSetChangedshowView(); ... ...

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

3 0
原创粉丝点击