Android getView方法优化简记
来源:互联网 发布:剑三盾太捏脸数据 编辑:程序博客网 时间:2024/04/27 14:34
Android getView方法优化简记
学习Android差不多半年,现在看来以前学习的终究太浅,重量不中质。看书也是囫囵吞枣,总想着看完再说,却没有想想自己究竟真正的掌握了什么。最近一直在反思之前的学习历程,这个getView方法的优化让我印象颇深,网上的资料数不胜数,说是优化,不如说是一种应该如此的学法。虽然只是入门的知识,但是很多基础教程上都没有提及。把它写下来,就是给自己提个醒,也算值得。
这里以ListView的getView()为例,刚学习Android的时候,重写ListView的Adapter时getView方法是这样写的:
@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = View.inflate(ctx, R.layout.layout_item, null);TextView tv1 = (TextView) view.findViewById(R.id.tv_1st);TextView tv2 = (TextView) view.findViewById(R.id.tv_2ed);tv1.setText(position + "");tv2.setText(strs[new Random().nextInt(strs.length)]);return view;}
这种写法就是一般的Android入门书里的学法,当ListView显示的数据较多时,在手机配置较差或模拟器中快速滑动列表时,特别容易出现内存溢出的错误,导致应用程序崩溃。
查看log:
在Android源码或是开发中应该这样写
@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = null;ViewHolder holder;if (convertView != null) { //复用控件view = convertView;holder = (ViewHolder) view.getTag();} else { //构造列表项控件,用ItemView进行缓存view = View.inflate(ctx, R.layout.layout_item, null);holder = new ViewHolder();holder.tv1 = (TextView) view.findViewById(R.id.tv_1st);holder.tv2 = (TextView) view.findViewById(R.id.tv_2ed);view.setTag(holder);}//绑定数据holder.tv1.setText("ID: " + position);holder.tv2.setText(strs[new Random().nextInt(strs.length)]);return view;}} //缓存数据项控件对象static class ViewHolder {TextView tv1;TextView tv2;}
这种写法为每个类表象都inflate了一个View对象,当列表项很多时会导致子控件的数量急剧膨胀,耗费大量的内存资源,甚至导致应用崩溃。Android的适配器在设计时,充分考虑了处理大规模数据的场景,为开发者提供了解决策略。在Adapter.getView方法中,有一个输入参数convertView,用于缓存最近一个失去可视状态的列表控件对象。当用户滚动列表时,处于可视状态的列表项会变成不可视状态,而不可视状态的列表则可能会变成可视状态。convertView便是用于缓存失去可视状态的列表项控件对象,通过Adapter.getVie方法传回开发者手中,开发者可以复用这个控件对象重新绑定即将可视的列表项数据,从而避免了构造新列表控件的开销。
另外,在使用convertView的时候,对列表项控件的子控件进行缓存可以节省列表项数据项绑定的开销,View.setTag方法可以将缓存放在对应的列表项控件中,节省调用View.findViewById方法造成的浪费。
通过列表项复用,可以有效地提高列表项的性能,节约内存开销,但同时它也增加了编程的复杂度,尤其是存在多种表项样式时,这种复杂度的增加也尤为明显。开发者需要根据列表项的数量和特征,选择合适的构造方法。
再看一下Android源码中的示例:
android/packages/apps/settings/src/com/android/settings @Override public View getView(int position, View convertView, ViewGroup parent) { // A ViewHolder keeps references to children views to avoid unnecessary calls // to findViewById() on each row. AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView); convertView = holder.rootView; MyApplicationInfo info = getItem(position); holder.appName.setText(info.label); if (info.info != null) { holder.appIcon.setImageDrawable(info.info.loadIcon(getPackageManager())); holder.appSize.setText(info.info.packageName); } else { holder.appIcon.setImageDrawable(null); holder.appSize.setText(""); } holder.disabled.setVisibility(View.GONE); holder.checkBox.setVisibility(View.GONE); return convertView; } }public class AppViewHolder { public ApplicationsState.AppEntry entry; public View rootView; public TextView appName; public ImageView appIcon; public TextView appSize; public TextView disabled; public CheckBox checkBox; static public AppViewHolder createOrRecycle(LayoutInflater inflater, View convertView) { if (convertView == null) { convertView = inflater.inflate(R.layout.manage_applications_item, null); // Creates a ViewHolder and store references to the two children views // we want to bind data to. AppViewHolder holder = new AppViewHolder(); holder.rootView = convertView; holder.appName = (TextView) convertView.findViewById(R.id.app_name); holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon); holder.appSize = (TextView) convertView.findViewById(R.id.app_size); holder.disabled = (TextView) convertView.findViewById(R.id.app_disabled); holder.checkBox = (CheckBox) convertView.findViewById(R.id.app_on_sdcard); convertView.setTag(holder); return holder; } else { // Get the ViewHolder back to get fast access to the TextView // and the ImageView. return (AppViewHolder)convertView.getTag(); } }
之前也曾经看过相关内容,可是却由于思考上的惰性,导致之后的写法还是刚接触时的样子。学习不能只是被动接受,学而不思则罔,古人说的太对了。
- Android getView方法优化简记
- Android ListView getView方法 性能优化
- Android ListView getView方法 性能优化【转】
- android listView 重写Adapter方法getView的性能优化问题
- ListView优化,和getView方法的研究
- listview的重写方法getview的优化
- [Android]ListView的Adapter.getView()方法中延迟加载图片的优化
- [Android]ListView的Adapter.getView()方法中延迟加载图片的优化
- Android Adapter以及getView()方法的理解
- Android Adapter以及getView()方法的理解
- BaseAdapter的getView方法中对setOnclickListener优化
- Android listview&gridview getview 方法多次调用问题解决方法
- Android listview&gridview getview 方法多次调用问题解决方法
- Android 记住baseAdapter的getview方法中position方法
- Android: Gallery的adapter中getView方法被执行多次
- Android中Adapter的getView方法复用view机制
- android adapter getView方法中return null发生的异常
- android listview 连续调用 getview调用getivew方法多次解决办法
- 隐忍
- C 数组
- Netflix推荐系统:从评分预测到消费者法则
- 如何利用8个8运算构成1000
- HDU-Tri Tiling-铺方格
- Android getView方法优化简记
- HDU 2159 FATE (二维完全背包)
- hadoop fs -ls command not found
- [转]VC中自动改变控件位置和大小的对话框类
- 贪心算法-均分纸牌-JAVA
- 【时间管理】纵向管理工作进程
- 163上传博客文章
- hibernate使用总结
- java中instanceof的用法