以通讯卫士黑名单为例进行分析:
1.当适配器作如下配置的时候:
private class CallSmsSafeAdapter extends BaseAdapter {@Overridepublic int getCount() {return infos.size();}@Overridepublic 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;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic 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;@Overridepublic int getCount() {return infos.size();}@Overridepublic 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;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic 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);
查询一次后将其信息保存,以后再查询就不必遍历所有控件。
优化如下:
至此,ListView适配器优化完成。private class CallSmsSafeAdapter extends BaseAdapter {private TextView tv_number;private TextView tv_mode;private ImageView iv_delete;@Overridepublic int getCount() {return infos.size();}@Overridepublic 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;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}}private class ViewHolder {private TextView tv_number;private TextView tv_mode;private ImageView iv_delete;}

浙公网安备 33010602011771号