Android性能優(yōu)化之ListView緩存機(jī)制
來(lái)源:程序員人生 發(fā)布時(shí)間:2014-09-27 02:12:14 閱讀次數(shù):1911次
要想優(yōu)化ListView首先要了解它的工作原理,列表的顯示需要三個(gè)元素:ListView、Adapter、顯示的數(shù)據(jù);
這里的Adapter就是用到了適配器模式,不管傳入的是什么View在ListView中都能顯示出來(lái)。
下面簡(jiǎn)單說(shuō)下上圖的原理:
1、如果你有幾千幾萬(wàn)甚至更多的選項(xiàng)(item)時(shí),其中只有可見(jiàn)的項(xiàng)目(滿屏顯示的Item數(shù)目)存在內(nèi)存(說(shuō)的優(yōu)化就是說(shuō)在內(nèi)存中的優(yōu)化!)中,其他的在Recycler中
2、ListView先請(qǐng)求一個(gè)type1視圖(getView)然后請(qǐng)求其他可見(jiàn)的項(xiàng)目。convertView在getView中是空(null)的,第一次都是為空的,只要顯示過(guò)了convertView都不為空,會(huì)保存在Recycler中
3、當(dāng)item1滾出屏幕,并且一個(gè)新的項(xiàng)目從屏幕低端上來(lái)時(shí),ListView再請(qǐng)求一個(gè)type1視圖。convertView此時(shí)不是空值了,它的值是item1。你只需設(shè)定新的數(shù)據(jù)然后返回convertView,不必重新創(chuàng)建一個(gè)視圖,省去了inflate和findViewById的時(shí)間,性能就得到了優(yōu)化。

了解了它的工作原理后,我們就可以重復(fù)利用convertView,只要不為空就直接使用,改變它的內(nèi)容就行了。
使用ListView的時(shí)候都會(huì)搭配一個(gè)Adapter,為了使得性能更優(yōu),ListView會(huì)緩存行item(某行對(duì)應(yīng)的View)。ListView通過(guò)Adapter的getView函數(shù)獲得每行的item。
package com.dzt.listviewdemo;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private ListAdapter adapter;
private ListView lv = null;
private ArrayList<String> list = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv_list);
adapter = new ListAdapter();
for (int i = 0; i < 100; i++) {
list.add("item " + i);
}
lv.setAdapter(adapter);
}
private class ListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
ListAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
System.out.println("getView " + position + " " + convertView);
viewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, null);
holder = new viewHolder();
holder.text = (TextView) convertView.findViewById(R.id.tv_text);
holder.image = (ImageView) convertView
.findViewById(R.id.iv_img);
convertView.setTag(holder);
} else {
holder = (viewHolder) convertView.getTag();
}
holder.text.setText(list.get(position));
if (position % 2 == 0) {
holder.image.setImageResource(R.drawable.ic_launcher);
} else {
holder.image.setImageResource(R.drawable.icon);
}
return convertView;
}
}
/**
* 使用一個(gè)類來(lái)保存Item中的元素
*
* @author Administrator
*
*/
public static class viewHolder {
public TextView text;
public ImageView image;
}
}
運(yùn)行效果

第一次打印的結(jié)果convertView都是為null

滑動(dòng)ListView后的打印

從上面的打印消息可以看出,Recycler中會(huì)保存七個(gè)convertView對(duì)象用來(lái)顯示Item,不管你有上千個(gè)Item,也只會(huì)創(chuàng)建顯示滿屏的convertView,這就大大節(jié)省了內(nèi)存,對(duì)viewHolder的Tag的使用也大大節(jié)省了性能開(kāi)銷(xiāo)
相關(guān)代碼下載:http://download.csdn.net/detail/deng0zhaotai/7842885
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)