您的位置:首页 > 其它

GridView异步加载中一次加载完所有数据问题的解决以及其原因分析

2015-06-17 15:16 453 查看
装载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0918/1693.html

今天在开发一个相册应用的时候遇到一个很奇怪的问题,用于显示照片的GridView在显示的时候,初次加载,getView就被调用了1000次,而我的所有图片也只有1000张,也就是说在还没有滚动的情况下GridView就已经把所有的数据显示完了(当然超出屏幕的是看不见的),但是GridView本身是只显示视野范围内的数据项的啊。如果这样GridView的子view复用还有什么意义,GridView一直都是按需加载的啊。

下面是getView中打印出来的position值



显示安卓系统中图片是肯定需要异步加载的,如果一次就异步的方式去加载1000张照片,所消耗的系统资源可想而知,实际情况是我的应用直接就黑屏了。而即便没有开启异步加载如果第一次getView就调用了1000次,那么说明一次就生成了1000个子View,这样虽然应用不会死,也会出现上图中的渲染警告:Skipped 77 frames! The application may be doing too much work on its main thread.

出现这个问题让我很无奈,因为我根本就不知道我到底哪里错了,我都是按照正常方式来使用GridView的。

经过无数次debug,终于找出了问题的所在。

为了复线出这种情况,先讲讲我是如何使用的。之所以把这两部分代码提出来,是因为用替换法我发现问题就出在这里。

用于显示照片的GridView的adapter中getView 是这样实现的:

其中mLoader.DisplayImage(mImageList.get(position), holder.imageView);是开启一个加载图片的线程,也就是异步加载。

R.layout.item_image代码如下:

如上使用,则会出现刚刚提到的怪异情况。

但是我发现在
ImageView
中,
android:layout_height
设置一个高度就不会出现这样的问题。或者是给
ImageView
设置一个padding也不会出现这样的问题,这些高度值我试了不同的数值,发现值越小,getView调用的次数越多,当为1px的时候差不多就接近1000次了,其实这个很好理解,因为值越小
每个item的高度越小,可见范围内就能显示越多的item。但是这个数值接近1000则给我我很大的触动。我一下意识到这个跟
ImageView
layout_height
wrap_content
有关。

因为ImageView的图片资源是异步加载,所以在getView返回
return
convertView的时候
ImageView其实是没有任何内容的,而[code]wrap_content
也就意味着其实际高度为0,因此不管你的
ImageView在异步数据完成之后有多大,GridView都认为自己的高度足以显示完所有的item(因为在返回
convertView
的时候高度为0)。[/code]

找到了问题之后我们对症下药,完美解决。

但是还是有必要总结一下出现这种情况的时机,因为一般情况很少见,我看网上也很少有人提到这个问题,唯一看到有人对此提问还是在stackoverflow上,而且没有人回答正确 http://stackoverflow.com/questions/11152992/forbid-gridview-to-load-all-views-at-once

1.item的xml中的控件不管有多少层,必须是可能有一个高度为0的情况出现,比如ImageView或者是
LinearLayout
高度为
wrap_content
,如果是有类似于TextView的控件,则绝不会出出现这种bug,因为TextView是有一个默认最小高度的。

2.通常情况下发生在异步加载的时候,因为即便ImageView或者是
LinearLayout
高度为
wrap_content,如果不是异步加载,他们的内容都会立马赋值,所以就会产生一个实际高度。


3.最普遍的是内容只是单个ImageView的情况,因为
wrap_content
的[code]ImageView
在没有设置图片资源之前,高度是为0的。而且真正需要异步加载的往往也只有
ImageView
。[/code]

最后给点建议:


虽然上面说item中有TextView绝不会出现无尽的加载完所有数据的异常情况,但是我们还是希望
TextView
(或者其他)能够在返回[code]
convertView
之前确保高度是和实际内容一致的,不然即便是没有加载很多,也是多余预期的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: