Android中对ListView的优化处理
搞Android开发的同学都知道,ListView的在实际项目开发中应用十分普遍,一般用来显示列表数据的,但这样就有个问题了。我们知道在实际项目中,列表数据量很大,有可能成千上万的大小,对于一般如TextView来说倒没什么,但如果是自定义的ViewGroup的话,里面可能有很多View,而占用内存最大的莫过于ImageView所承载的图片数据了,那么就很有必要来优化一下ListView了,我们先从它的工作原理开始。
ListView工作原理:
我们知道ListView是通过Adapter来将要显示的数据映射到上面来显示的。首先,Adapter会调用方法getCount()来计算出当前的数据的大小,根据返回的值来指定ListView的长度,然后一条条的绘制直至绘制完成。也就是说,getCount()返回多少,ListView就是要求Adapter调用多少次getView()来绘制View。问题产生了,如果有上万条的数据要显示的话,为每条数据创建一个View吗?这显然是不可能的。实际上,Android已经对显示的View进行了缓存,在Android中有个叫做Recycler的,它主要是用来优化处理不被显示在视图的所有Item数据,而当前显示的Item就需要我们在内存中进行优化了。当我们滑动ListView加载数据的时候,即当Item1画出屏幕,而又有新的Item加载进来的时候,当前的convertView不为空了而存放的是Item1,我们只需要更新数据返回convertView即可,不需要重新去创建新的视图,这样大大提高运行速度,减少了内存资源的占用,优化的结论:“重用convertView”。
具体可参看代码:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
mHolder = new ViewHolder();
if (convertView == null) {
this.mInflater = LayoutInflater.from(mContext);
convertView=mInflater.inflate(R.layout.view_company_item,null);
mHolder.image01 = (ImageView) convertView.findViewById(R.id.company_img_01);
mHolder.text01 = (TextView) convertView.findViewById(R.id.company_text_01);
mHolder.image02 = (ImageView) convertView.findViewById(R.id.company_img_02);
mHolder.text02 = (TextView) convertView.findViewById(R.id.company_text_02);
mHolder.image03 = (ImageView) convertView.findViewById(R.id.company_img_03);
mHolder.text03 = (TextView) convertView.findViewById(R.id.company_text_03);
convertView.setTag(mHolder);
} else
mHolder = (ViewHolder) convertView.getTag();
// 自定义处理逻辑
return convertView;
}
另外,我们最好在内部定义内部类ViewHolder,如下:
public class ViewHolder {
ImageView image01;
TextView text01;
ImageView image02;
TextView text02;
ImageView image03;
TextView text03;
}
这样做的目的很明确,就是只创建一次View,不需要重复创建,提高效率和减少占用内存。
优化注意点如下:
1、ViewHolder Tag和convertView使用必不可少。
2、ListView中涉及到图片的处理:
A、不要直接取图片,先将图片缩略化,用BitmapFactory.Options保存图片信息,不加载图片到内存。
B、将得到的图片数据进行压缩处理。
C、在ListView取图片的时候,不要直接用URL那图片,而要以若引用代替强引用来存放图片的简单信息,而不是实际图片哦。例如:SoftReference、WeakHashMap等。
D、在getView()处理的图片转换的时候用到的中间变量要及时的处理释放。
3、在Adapter中尽量避免使用static类型的全局变量。
4、如果为了满足需求下必须使用Context的话:Context尽量使用Application Context,因为Application的Context的生命周期比较长,引用它不会出现内存泄露的问题。
5、尽量避免在ListView适配器中使用线程,因为线程产生内存泄露的主要原因在于线程生命周期的不可控制。
ListView优化三原则 :
1.复用convertView
在getView中,判断convertView是否为空,如果不为空,可复用。
2.异步加载图片
item中如果包含有webimage,那么最好异步加载。
3.快速滑动时不显示图片
当快速滑动列表时(SCROLL_STATE_FLING),item中的图片或获取需要消耗资源的view,可以不显示出来;而处于其他两种状态(SCROLL_STATE_IDLE 和SCROLL_STATE_TOUCH_SCROLL),则将那些view显示出来。
对于ListView的优化处理,暂时总结道这里,如果各位同学有更好的建议,别忘了让我学习一下,一起进步吧!
技术交流群:179914858