Android开发:优化ListView实践解析

 在看了一些vogella的文章之后,发现关于android listview性能优化这一段很有意思,于是实践了一下,经过优化,性能确实提升不少!

先看看优化前和优化后的比较:

优化前的log截图:

开发:优化ListView实践解析-">

优化后的log截图:

并且,在不停滚动ListView的过程中,优化之前会出现ANR现象,在AVD上特别容易复现:

然后,优化后显得很流畅,附上对于的log截图:

下面附上相关代码分析:

ListView中的每一个Item由一个ImageView 和一个TextView组成

Layout:

 
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3. android:layout_width="fill_parent" 
  4. android:layout_height="fill_parent" 
  5. android:orientation="horizontal" > 
  6. <ImageView android:id="@+id/imageView" 
  7. android:layout_width="wrap_content" 
  8. android:layout_height="fill_parent" />" 
  9. <TextView android:id="@+id/textView" 
  10. android:layout_width="wrap_content" 
  11. android:layout_height="fill_parent" 
  12. android:layout_marginLeft="15dp" 
  13. android:gravity="center_vertical" /> 
  14. </LinearLayout> 

Activity继承自ListActivity,我故意增加了Item,方便测试,效果更明显:

 
  1. public class ListViewDemo extends ListActivity{ 
  2. private final String[] mItems = new String[] { "Android", "iPhone", 
  3. "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7", 
  4. "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", 
  5. "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", 
  6. "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", 
  7. "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", 
  8. "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", 
  9. "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", 
  10. "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", 
  11. "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", 
  12.  "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", 
  13. "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", 
  14. "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", 
  15. "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", 
  16. "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", 
  17.  "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", 
  18. "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", 
  19. "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", 
  20. "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", 
  21.  "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", 
  22.  "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", 
  23. "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", 
  24. "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", 
  25. "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", 
  26. "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", 
  27. "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", 
  28. "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", 
  29. "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2" }; 
  30.  @Override 
  31. public void onCreate(Bundle savedInstanceState) { 
  32.     super.onCreate(savedInstanceState); 
  33.      ListViewArrayAdapter adapter = new ListViewArrayAdapter(this, mItems); 
  34.       getListView().setAdapter(adapter); 
  35.     } 

然后custom Adapter,优化之前的adapter:

 
  1. @Override 
  2.       public View getView(int position, View convertView, ViewGroup parent) { 
  3.         long start = System.currentTimeMillis(); 
  4.         LayoutInflater inflater = (LayoutInflater) mContext.getLayoutInflater(); 
  5.         View rowView = inflater.inflate(mViewResourceId, parent, false); 
  6.         TextView textView = (TextView) rowView 
  7.                 .findViewById(mTextViewResourceId); 
  8.         ImageView imageView = (ImageView) rowView 
  9.                 .findViewById(mImageViewResourceId); 
  10.         textView.setText(mNames[position]); 
  11.         String s = mNames[position]; 
  12.         if (s.startsWith("Windows7") || s.startsWith("iPhone")) { 
  13.             imageView.setImageResource(R.drawable.no); 
  14.         } else { 
  15.             imageView.setImageResource(R.drawable.yes); 
  16.         } 
  17.               
  18.        Log.v("jerikc","cost time = " + (System.currentTimeMillis() - start)); 
  19.       return rowView; 

优化之后的Adapter:

 
  1. public class ListViewArrayAdapter extends ArrayAdapter<String>{ 
  2.        private final Activity mContext; 
  3.        private final String[] mNames; 
  4.        private final static int mViewResourceId = R.layout.text_image_row_layout; 
  5.        private final static int mTextViewResourceId = R.id.textView; 
  6.        private final static int mImageViewResourceId = R.id.imageView; 
  7.     static class ViewHolder { 
  8.         public TextView text; 
  9.         public ImageView image; 
  10.     }     
  11.        public ListViewArrayAdapter(Activity context, String[] names) { 
  12.         super(context, mViewResourceId, names);  
  13.         this.mContext = context; 
  14.         this.mNames = names; 
  15.         } 
  16. @Override 
  17.     public View getView(int position, View convertView, ViewGroup parent) { 
  18.        long start = System.currentTimeMillis(); 
  19.         View rowView = convertView; 
  20.      if (rowView == null) { 
  21.          LayoutInflater inflater = mContext.getLayoutInflater(); 
  22.           rowView = inflater.inflate(mViewResourceId, null); 
  23.          ViewHolder viewHolder = new ViewHolder(); 
  24.         viewHolder.text = (TextView) rowView.findViewById(mTextViewResourceId); 
  25.         viewHolder.image = (ImageView) rowView.findViewById(mImageViewResourceId); 
  26.          rowView.setTag(viewHolder); 
  27.         } 
  28.        ViewHolder holder = (ViewHolder) rowView.getTag(); 
  29.        String s = mNames[position]; 
  30.        holder.text.setText(s); 
  31.       if (s.startsWith("Windows7") || s.startsWith("iPhone")) { 
  32.           holder.image.setImageResource(R.drawable.no); 
  33.         } else { 
  34.            holder.image.setImageResource(R.drawable.yes); 
  35.        } 
  36.        Log.v("jerikc","cost time = " + (System.currentTimeMillis() - start)); 
  37.         return rowView; 
  38.     } 

优化的大致思想就是:优化之前,每次加载item的时候,都要加载一下布局文件,然后生成一个新的row View对象,然后通过View找到对应的ImageView和TextView,正如我们所知道的那样,加载布局文件时很耗时的,特别是在操作比较频繁 情况下,这是不可忍受的,所以会导致ANR现象。

因此,我们可以重复利用已不可见的row View对象。Android中,当它决定让row View对象不可见的时候,它允许通过getView方法中的convertView参数来重复利用刚刚不可见的row View对象。

在优化的过程中,第一次加载的时候,我们需要把相关的数据保存起来,而View有一个方法setTag,该方法可用来保存一些数据结构。我们一个row View对象是由ImageView和TextView空间组成的,因此定义一个ViewHolder来保存ImageView和TextView对象。 在重复利用的过程中,只需简单修改它们的值,而不用再次findViewById。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索ubuntu
, android adapter
, textview
, 优化
, imageview
, max7456
, os x
, os
, inflate
, viewholder
, convertview
, max
, windows7
max()
,以便于您获取更多的相关知识。

时间: 2024-09-19 09:13:49

Android开发:优化ListView实践解析的相关文章

android开发中listview添加图片

问题描述 android开发中listview添加图片 map1.put("image",R.drawable.jiantou); 我在listview中添加图像时,引用图像的地址,如上所示,但提示错误The method put(String, String) in the type HashMap is not applicable for the arguments (String, int) 但我看别人的代码都可以直接引用图像地址的,请大神帮忙解决一下,谢啦!! 解决方案 Ma

Android开发优化之——使用软引用和弱引用

Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. 如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它:如果内存空间不足了,就会回收这些对象的内存.只要垃圾回收器没有回收它,该对象就可以被程序使用.软引用可用来实现内存敏感的高速缓存.软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,J

android 开发 json多层嵌套解析

问题描述 android 开发 json多层嵌套解析 向那种单层的数组我就会解析,向这种多层的我就不会了,都说是一层一层往下解析,就是不会,求大神指点,不要用Gson之类的框架,那些我会,谢谢 { "OK": 0, "obj": { "list": [ { "id": "8005285", "tour": { "id": "87962435", &

Android开发中Listview动态加载数据的方法示例

本文实例讲述了Android开发中Listview动态加载数据的方法.分享给大家供大家参考,具体如下: 最近在研究网络数据加载的问题,比如我有几百,甚至上千条数据,这些数据如果一次性全部加载到arraylist,然后再加载到Listview中.我们必然会去单独开线程来做,这样造成的结果就是会出现等待时间很长,用户体验非常不好.我的想法是动态加载数据,第一次加载十条,然后往下面滑动的时候再追加十条,再往下面滑动的时候再去追加,这样大大减少了用户等待的时间,同时给处理数据留下了时间.网上看到了这样一

解析Android开发优化之:从代码角度进行优化的技巧_Android

通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻辑,但是性能不一定是最优化的.一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构.重构的好处有很多,其中一点,就是对代码进行优化,提高软件的性能.下面我们就从几个方面来了解Android开发过程中的代码优化. 1)静态变量引起内存泄露 在代码优化的过程中,我们需要对代码中的静态变量特别留意.静态变量是类相关的变量,它的生命周期是从这个类被声明,到这个类彻底被垃圾回收器回收才会被销毁.所以,一般情况下,静态变量

浅谈Android开发中ListView控件性能的一些优化方法

ListView优化一直是一个老生常谈的问题,不管是面试还是平常的开发中,ListView永远不会被忽略掉,那么这篇文章我们来看看如何最大化的优化ListView的性能. 1.在adapter中的getView方法中尽量少使用逻辑 2.尽最大可能避免GC 3.滑动的时候不加载图片 4.将ListView的scrollingCache和animateCache设置为false 5.item的布局层级越少越好 6.使用ViewHolder 下面就具体来看一些 1.在adapter中的getView方

Android] Android开发优化之——从代码角度进行优化

通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻辑,但是性能不一定是最优化的.一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构.重构的好处有很多,其中一点,就是对代码进行优化,提高软件的性能.下面我们就从几个方面来了解Android开发过程中的代码优化.   1)静态变量引起内存泄露 在代码优化的过程中,我们需要对代码中的静态变量特别留意.静态变量是类相关的变量,它的生命周期是从这个类被声明,到这个类彻底被垃圾回收器回收才会被销毁.所以,一般情况下,静态

Android入门之ListView应用解析(一)_Android

Android中的ListView是一个经常用到的控件,ListView里面的每个子项Item可以使一个字符串,也可以是一个组合控件.本文先来说说ListView的实现: 1.准备ListView要显示的数据: 2.使用 一维或多维 动态数组 保存数据: 3.构建适配器 , 简单地来说, 适配器就是 Item数组 , 动态数组 有多少元素就生成多少个Item: 4.把 适配器 添加到ListView,并显示出来. 接下来,看看本文代码所实现的ListView效果:   接下来,就开始UI的XML

android开发中ListView与Adapter使用要点介绍_Android

1. Adapter.getView() public View getView(int position, View convertView , ViewGroup parent){...} 这个方法就是用来获得指定位置要显示的View.官网解释如下: Get a View that displays the data at the specified position in the data set. You can either create a View manually or infl