以通讯卫士黑名单为例进行分析:
1.当适配器作如下配置的时候:
private class CallSmsSafeAdapter extends BaseAdapter {
@Override
public int getCount() {
return infos.size();
}
@Override
public View getView(final int position, View convertView,ViewGroup parent) {
Log.i(TAG, "创建新的View对象" + position);
View view = View.inflate(getApplicationContext(),R.layout.list_callsmssafe_item, null);
TextView tv_number = (TextView) view.findViewById(R.id.tv_number);
TextView tv_mode = (TextView) view.findViewById(R.id.tv_mode);
ImageView iv_delete = (ImageView) view.findViewById(R.id.iv_delete);
String number = infos.get(position).getNumber();
tv_number.setText(number);
String mode = infos.get(position).getMode();
if ("1".equals(mode)) {
} else if ("2".equals(mode)) {
tv_mode.setText("短信拦截");
} else if ("3".equals(mode)) {
tv_mode.setText("电话+短信拦截");
}
return view;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
2.每次都新创建一个ListView对象,产生大量的内存垃圾,很快就产生OutOfMemoryError,因此要对内存缓存加以复用!
代码做如下调整:
private class CallSmsSafeAdapter extends BaseAdapter {
private TextView tv_number;
private TextView tv_mode;
private ImageView iv_delete;
@Override
public int getCount() {
return infos.size();
}
@Override
public View getView(final int position, View convertView,ViewGroup parent) {
View view;
// 为了减少view对象创建的个数,使用历史缓存
// convertView instanceof RelativeLayout,这里都是同种缓存可以不写
if(convertView!=null && convertView instanceof RelativeLayout) {
Log.i(TAG, "使用历史缓存的View对象" + position);
view = convertView;
} else {
Log.i(TAG, "创建新的View对象" + position);
view = View.inflate(getApplicationContext(),R.layout.list_callsmssafe_item, null);
tv_number = (TextView) view.findViewById(R.id.tv_number);
tv_mode = (TextView) view.findViewById(R.id.tv_mode);
iv_delete = (ImageView) view.findViewById(R.id.iv_delete);
}
String number = infos.get(position).getNumber();
tv_number.setText(number);
String mode = infos.get(position).getMode();
if ("1".equals(mode)) {
} else if ("2".equals(mode)) {
tv_mode.setText("短信拦截");
} else if ("3".equals(mode)) {
tv_mode.setText("电话+短信拦截");
}
return view;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
3.使用历史缓存后优化性能已经很高,但是每次还是要执行如下查询的代码,还有进一步优化的空间。
tv_number = (TextView) view.findViewById(R.id.tv_number);
tv_mode = (TextView) view.findViewById(R.id.tv_mode);
iv_delete = (ImageView) view.findViewById(R.id.iv_delete);
查询一次后将其信息保存,以后再查询就不必遍历所有控件。
优化如下:
private class CallSmsSafeAdapter extends BaseAdapter {
private TextView tv_number;
private TextView tv_mode;
private ImageView iv_delete;
@Override
public int getCount() {
return infos.size();
}
@Override
public View getView(final int position, View convertView,ViewGroup parent) {
View view;
ViewHolder holder;
// 为了减少view对象创建的个数,使用历史缓存
// convertView instanceof RelativeLayout,这里都是同种缓存可以不写
if(convertView!=null && convertView instanceof RelativeLayout) {
Log.i(TAG, "使用历史缓存的View对象" + position);
view = convertView;
holder = (ViewHolder) view.getTag();//取出记事本查找
} else {
Log.i(TAG, "创建新的View对象" + position);
holder = new ViewHolder();// 买了一个笔记本,记录孩子信息
view = View.inflate(getApplicationContext(),R.layout.list_callsmssafe_item, null);
holder.tv_number = (TextView) view.findViewById(R.id.tv_number);
holder.tv_mode = (TextView) view.findViewById(R.id.tv_mode);
holder.iv_delete = (ImageView) view.findViewById(R.id.iv_delete);
view.setTag(holder);// 把记事本放在口袋
}
String number = infos.get(position).getNumber();
holder.tv_number.setText(number);
String mode = infos.get(position).getMode();
if ("1".equals(mode)) {
} else if ("2".equals(mode)) {
holder.tv_mode.setText("短信拦截");
} else if ("3".equals(mode)) {
holder.tv_mode.setText("电话+短信拦截");
}
return view;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
private class ViewHolder {
private TextView tv_number;
private TextView tv_mode;
private ImageView iv_delete;
}至此, ListView适配器优化完成。