[置顶] Android中对ListView的优化处理

时间:2021-04-28 06:13:28

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  TagconvertView使用必不可少。

2、ListView中涉及到图片的处理:

A、不要直接取图片,先将图片缩略化,用BitmapFactory.Options保存图片信息,不加载图片到内存。

B、将得到的图片数据进行压缩处理。

C、ListView取图片的时候,不要直接用URL那图片,而要以若引用代替强引用来存放图片的简单信息,而不是实际图片哦。例如:SoftReferenceWeakHashMap等。

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