原创 Android 笔记之 listview 性能优化

2014-8-15 11:57 2024 33 33 分类: 软件与OS 文集: Android

列表显示需要三个元素,

1listview 视图,用来显示列表的View ;

2)适配器,用来把数据映射到listView上面的

3)数据,具体将被映射的数据,包括字符串,图片或者基本自定义的组件也行。

 

适配器分为三种,

ArrayAdapter,SimpleAdapter和SimpleCursorAdapter

这三者的区别不过是数据源不同而已。

ArrayAdapter就是数组适配器,具体的就是字符串数组;

SimpleAdapter就是简单适配器,但是不太简单,它的数据源就是List<Map<String,?>>,可以在Map里面放上各种各样的组件。

SimpleCursorAdapter 简单游标适配器,以数据库查询而来的游标作为数据源。

 

说完分类后再说ListView 的工作原理

 

Android系统在绘制ListView之前,先调用  getCount()方法,来获得将要绘制的列表有多长。然后调用getView方法,来获得一个View或者复杂一点的就是ViewGroup 。有几个listView子项,在屏幕最多能显示的前提下,显示最多个,比如说屏幕能显示5个,而getCount()返回10个,那么这首先显示的5Item就是返回了5View,进行显示的。但是当下滑的时候,是不是又新建返回一个View呢?假如有上千万个呢?显然这样新建的话,最终内存会被耗尽。Android 已经做了优化,有个构件,叫做Recycler,它负责存放失去显示的子项View对象,比如说1~5view在显示,现在往上滑动,1view就进入Recycler,由于马上第六条的显示就需要用到一个view,那么这时候回收了的1view就会授予给6号,进行显示,而不必新建一个view对象了,从而节省和优化内存。

 

下面说优化方案:

1使用自定义的视图缓存类

就是自定义一个视图缓存类,在这个类中保存我们在item中使用到的视图的引用,通过convertViewsetTag方法和getTag方法来存储这个视图缓存类引用和重新获取这个视图缓存类引用,其目的也是为了减少重复创建视图时的开销。tag就是标签的意思,但是,它不像ID一样用来表示view的,从本质上讲它是与某一个view绑定的额外的信息,setTagObject obj)中输入就是对象,可以是任意的对象信息。

 

 

 

 

2)如果listview子项中包括图片,不要直接加载到内存里,因为你不知道图片有多大,而虚拟机中分配给堆的内存最大只有16M那么少。很容易就出现OOM。为了避免这种情况,可以对图片进行两步操作,一是利用BitmapFactory.Options()这个方法可以不加载图片到内存而获得图片大小,然后就对图片进行边界压缩;第二步是使用软引用来代替强引用来存储图片的引用。如可定义这么一个图片缓存。

 

private Map<String, SoftReference<Bitmap>> imageCache = Collections

.synchronizedMap(new LinkedHashMap<String, SoftReference<Bitmap>>(

10, 0.75f, false));

 

3)避免在ListView中使用线程,因为线程的生命周期不可控制,你不知道它什么时候执行完毕,容易造成内存泄漏。

 

 

文章评论0条评论)

登录后参与讨论
我要评论
0
33
关闭 站长推荐上一条 /2 下一条