北京做网站的公司东道,织梦网站怎么修改内容,wordpress默认主题,哪个网站适合 做红本抵押前言 ListView是Android中最常用的控件#xff0c;通过适配器来进行数据适配然后显示出来#xff0c;而其性能是个很值得研究的话题。本文与你一起探讨Google I/O提供的优化Adapter方案#xff0c;欢迎大家交流。 声明 欢迎转载#xff0c;但请保留文章原始出处:) 博客园通过适配器来进行数据适配然后显示出来而其性能是个很值得研究的话题。本文与你一起探讨Google I/O提供的优化Adapter方案欢迎大家交流。 声明 欢迎转载但请保留文章原始出处:) 博客园http://www.cnblogs.com 农民伯伯 http://over140.cnblogs.com 正文 一、准备 1.1 了解关于Google IO大会关于Adapter的优化参考以下文章 Android开发之ListView 适配器Adapter优化 Android开发——09Google I/O之让Android UI性能更高效(1) PDF下载Google IO.pdf 1.2 准备测试代码 Activity private TestAdapter mAdapter; private String[] mArrData; private TextView mTV; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTV (TextView) findViewById(R.id.tvShow); mArrData new String[1000]; for (int i 0; i 1000; i) { mArrData[i] Google IO Adapter i; } mAdapter new TestAdapter(this, mArrData); ((ListView) findViewById(android.R.id.list)).setAdapter(mAdapter); } 代码说明模拟一千条数据TestAdapter继承自BaseAdaptermain.xml见文章末尾下载。 二、测试 测试方法手动滑动ListView至position至50然后往回滑动充分利用convertView不等于null的代码段。 2.1 方案一 按照Google I/O介绍的第二种方案把item子元素分别改为4个和10个这样效果更佳明显。 2.1.1 测试代码 private int count 0; private long sum 0L; Override public View getView(int position, View convertView, ViewGroup parent) { //开始计时 long startTime System.nanoTime(); if (convertView null) { convertView mInflater.inflate(R.layout.list_item_icon_text, null); } ((ImageView) convertView.findViewById(R.id.icon1)).setImageResource(R.drawable.icon); ((TextView) convertView.findViewById(R.id.text1)).setText(mData[position]); ((ImageView) convertView.findViewById(R.id.icon2)).setImageResource(R.drawable.icon); ((TextView) convertView.findViewById(R.id.text2)).setText(mData[position]); //停止计时 long endTime System.nanoTime(); //计算耗时 long val (endTime - startTime) / 1000L; Log.e(Test, Position: position : val); if (count 100) { if (val 1000L) { sum val; count; } } else mTV.setText(String.valueOf(sum / 100L));//显示统计结果 return convertView; } 2.1.2 测试结果微秒除以1000见代码 次数 4个子元素 10个子元素 第一次 366 723 第二次 356 689 第三次 371 692 第四次 356 696 第五次 371 662 2.2 方案二 按照Google I/O介绍的第三种方案是把item子元素分别改为4个和10个。 2.2.1 测试代码 private int count 0; private long sum 0L; Override public View getView(int position, View convertView, ViewGroup parent) { // 开始计时 long startTime System.nanoTime(); ViewHolder holder; if (convertView null) { convertView mInflater.inflate(R.layout.list_item_icon_text, null); holder new ViewHolder(); holder.icon1 (ImageView) convertView.findViewById(R.id.icon1); holder.text1 (TextView) convertView.findViewById(R.id.text1); holder.icon2 (ImageView) convertView.findViewById(R.id.icon2); holder.text2 (TextView) convertView.findViewById(R.id.text2); convertView.setTag(holder); } else{ holder (ViewHolder)convertView.getTag(); } holder.icon1.setImageResource(R.drawable.icon); holder.text1.setText(mData[position]); holder.icon2 .setImageResource(R.drawable.icon); holder.text2.setText(mData[position]); // 停止计时 long endTime System.nanoTime(); // 计算耗时 long val (endTime - startTime) / 1000L; Log.e(Test, Position: position : val); if (count 100) { if (val 1000L) { sum val; count; } } else mTV.setText(String.valueOf(sum / 100L));// 显示统计结果 return convertView; } } static class ViewHolder { TextView text1; ImageView icon1; TextView text2; ImageView icon2; } 2.2.2 测试结果微秒除以1000见代码 次数 4个子元素 10个子元素 第一次 311 417 第二次 291 441 第三次 302 462 第四次 286 444 第五次 299 436 2.3 方案三 此方案为“Henry Hu”提示API Level 4以上提供这里顺带测试了一下不使用静态内部类情况下性能。 2.3.1 测试代码 Override public View getView(int position, View convertView, ViewGroup parent) { // 开始计时 long startTime System.nanoTime(); if (convertView null) { convertView mInflater.inflate(R.layout.list_item_icon_text, null); convertView.setTag(R.id.icon1, convertView.findViewById(R.id.icon1)); convertView.setTag(R.id.text1, convertView.findViewById(R.id.text1)); convertView.setTag(R.id.icon2, convertView.findViewById(R.id.icon2)); convertView.setTag(R.id.text2, convertView.findViewById(R.id.text2)); } ((ImageView) convertView.getTag(R.id.icon1)).setImageResource(R.drawable.icon); ((ImageView) convertView.getTag(R.id.icon2)).setImageResource(R.drawable.icon); ((TextView) convertView.getTag(R.id.text1)).setText(mData[position]); ((TextView) convertView.getTag(R.id.text2)).setText(mData[position]); // 停止计时 long endTime System.nanoTime(); // 计算耗时 long val (endTime - startTime) / 1000L; Log.e(Test, Position: position : val); if (count 100) { if (val 1000L) { sum val; count; } } else mTV.setText(String.valueOf(sum / 100L) : nullcount);// 显示统计结果 return convertView; } 2.3.2 测试结果微秒除以1000见代码 第一次450 第二次467 第三次472 第四次451 第五次441 四、总结 4.1 首先有一个认识是错误的我们先来看截图 可以发现只有第一屏可视范围调用getView所消耗的时间远远多于后面的通过对 convertView null内代码监控也是同样的结果。也就是说ListView仅仅缓存了可视范围内的View随后的滚动都是对这些View进行数据更新。不管你有多少数据他都只用ArrayList缓存可视范围内的View这样保证了性能也造成了我以为ListView只缓存View结构不缓存数据的假相不会只有我一人这么认为吧- - #。这也能解释为什么GOOGLE优化方案一比二高很多的原因。那么剩下的也就只有findViewById比较耗时了。据此大家可以看看AbsListView的源代码看看 obtainView这个方法内的代码及RecycleBin这个类的实现欢迎分享。 此外了解这个原理了那么以下代码不运行你可能猜到结果了 if (convertView null) { convertView mInflater.inflate(R.layout.list_item_icon_text, null); ((ImageView) convertView.findViewById(R.id.icon1)).setImageResource(R.drawable.icon); ((TextView) convertView.findViewById(R.id.text1)).setText(mData[position]); ((ImageView) convertView.findViewById(R.id.icon2)).setImageResource(R.drawable.icon); ((TextView) convertView.findViewById(R.id.text2)).setText(mData[position]); } else return convertView; 没错你会发现滚动时会重复显示第一屏的数据 子控件里的事件因为是同一个控件也可以直接放到convertView null 代码块内部如果需要交互数据比如position可以通过tag方式来设置并获取当前数据。 4.2 本文方案一与方案二对比 这里推荐如果只是一般的应用一般指子控件不多无需都是用静态内部类来优化使用第二种方案即可反之对性能要求较高时可采用。此外需要提醒的是这里也是用空间换时间的做法View本身因为setTag而会占用更多的内存还会增加代码量而findViewById会临时消耗更多的内存所以不可盲目使用依实际情况而定。 4.3 方案三 此方案为“Henry Hu”提示API Level 4以上支持原理和方案三一致减少findViewById次数但是从测试结果来看效果并不理想这里不再做进一步的测试。 五、推荐文章 Android谁动了我的内存(1) Android 内存泄漏调试 六、后期维护 2011-3-30 参见这里(http://www.javaeye.com/topic/971782)的讨论据此将计划写续篇。 结束 对于Google I/O大会这个优化方案一直抱迟疑态度此番测试总算是有了更进一步的了解欢迎大家先测试后交流看看还有什么办法能够再优化一点。 转载于:https://www.cnblogs.com/lanzhi/p/6469678.html