引言
今天无意中翻看项目代码,发现有一个list-adapter没有使用viewholder也没有使用settag、gettag,心里很紧张,这个页面使用频率很高,如果oom可不好。奇怪,为什么没有测试和我反映呢?
分析问题
项目里使用了网络上的一个ViewFindUtils类,里面有一个hold方法和一个find方法,我的listview中只调了find方法,find方法里只是一个findviewbyid,没有使用viewholder,自然也就没有settag及gettag。
public static <T extends View> T find(View view, int id)
{
return (T) view.findViewById(id);
}
我先想先用ViewFindUtils类里,另外一个hold方法(看注释是万能holder),结果用不了,却一直报错java.lang.ClassCastException: java.lang.String cannot be cast to android.util.SparseArray,在github上找了好多相同的代码,却看不到使用那段代码的语句,索性先放一放。
写代码分析
一直很好奇,安卓listview最大支持多少条目,今天试了一下,每个item包含一个imageview,一个textview。
public class MyListAdapter extends BaseAdapter {
private List<String> mTestList;
private Context mContext;
private LayoutInflater mInflater;
public MyListAdapter(Context context) {
this.mContext = context;
this.mInflater = LayoutInflater.from(mContext);
mTestList = new ArrayList<String>();
for (int i = 0; i < 1000000; i++) {
mTestList.add("第"+i+"个");
}
}
@Override
public int getCount() {
return mTestList.size();
}
@Override
public Object getItem(int position) {
return mTestList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = mInflater.inflate(R.layout.item_lsv_main, null);
}
//暂时啥也不干,不settag,不gettag
return convertView;
}
}
在没有findviewbyid没有viewholder的情况下,不断加大数据源,最终在红米2手机上测的150万数据会oom。
这里以100万数据源作为测试:
1.加上以下语句
TextView nameTxtv = (TextView) onvertView.findViewById(R.id.item_name_txtv);
nameTxtv.setText(mTestList.get(position));
很流畅,依然不会奔溃。
2.多加几个findviewbyid
几乎没影响
3.加入viewholder、settag、gettag
依然很流畅
4.去掉if(convertView == null)这个条件
拖拽时候会卡断,拖的越快,卡的越厉害,但是没有oom
结论:
原来listview的adapter设配器,只要用到if(convertView == null)这个条件,相对来说就没啥影响,即使不使用viewholder,也没多大关系,程序不会oom。但是呢,为了节省点内存,尽量还是加上吧,或者直接使用万能adapter,这些代码一行都不用管。