Listview:性能优化
1:Listview是需要和适配器配合使用的,
常用的适配器有arrayAdapter,SimplerAdapter,SimpleCursorAdapter,BaseAdapter,
一般情况下我使用的是继承BaseAdapter,实现它的四个方法,其中最重要的两个方法,getCount,和getView,
在不做任何处理的情况下getview每次都重新生成一个view,这样的结果就是很消耗内存,
谷歌官网提供了优化listview内存的方法,通过ConvertView的复用和使用ViewHolder来减少findbyid的次数,从而达到控件的复用和减少cpu的消耗,
但是因为控件的复用,在加载图片的时候,复用的控件里面有残留的图片,从而造成图片的错位,
所以我们必须在初始化的时候设置默认图片来清除缓存的图片,同时在加载的时候图片的时候,如果不进行listview的性能优化,就会造成OOM,
所以一般情况下我们会加载二次采样过后的url,同时我们会进行三级缓存的处理,
三级缓存:
1:首先从强引用中获取(Lrucache),如果强引用中没有,再去软引用中获取(SoftReference),如果软引用再去SD卡获取(SD卡被DisLrucache替代掉),如果这三级缓存中都没有,就开启网络去请求图片,请求回来的图片,在加入到强引用中(Lrucache),如果强引用已经满了,这时候,强引用通过Lrucache算法,删除掉一些最近不常用的图片,这时候咱们把这些图片放到软引用里面,(当内存不足到时候软引用就会被被垃圾回收机制回收),如果垃圾回收机制没有,软引用也满了,将不常用的图片移除掉,同时加入到SD卡,(现在被DisLrucache替代)
(key 一般使用的是网络请求图片的url,来保证唯一性,一般情况下我会做一下MD5加密,这样做的目的是为了保证不会出现非法字符)
现在SoftReference已经被替代掉,现在我们只使用两级缓存,在加网络,Lrucache,DisLrucache
LRC算法:最近最少使用的(内部如何实现的)
强引用:Lrucache
软引用:SoftReference
弱引用:weak(随时被垃圾回收机制回收)
虚引用:phantomreference
可定义图片异步加载工具类,核心方式实现思路如下:
1.先从内存缓存(Map
2.获取不到的话从本地SD卡里获取并显示
3.都获取不到的话通过子线程从网络加载图片并保存到内存及SD卡中并通过handler显示
二次采样:
http://m.blog.csdn.net/article/details?id=51245133
既然是二次采样,那当然要分为两步了,下面我们来说说每次采样的主要工作:
第一次采样我主要是想要获得图片的压缩比例,假如说我有一张图片是200*200,那么我想把这张图片的缩略图显示在一个50*50的ImageView上,那我的压缩比例应该为4,那么这个4应该怎么样来获得呢?这就是我们第一步的操作了,我先加载图片的边界到内存中,这个加载操作并不会耗费多少内存,加载到内存之后,我就可以获得这张图片的宽高参数,然后根据图片的宽高,再结合控件的宽高计算出缩放比例。
在第一次采样的基础上,我来进行二次采样。二次采样的时候,我把第一次采样后算出来的结果作为一个参数传递给第BitmapFactory,这样在加载图片的时候系统就不会将整张图片加载进来了,而是只会加载该图片的一张缩略图进来,这样不仅提高了加载速率,而且也极大的节省了内存,而且对于用户来说,他也不会有视觉上的差异
第一次采样:首先获取new BitmapFactory.Options()获取option对象,inJustDecodeBounds
设置为true只会加载图片的边框进来,并不会加载图片具体的像素点,通过BitmapFactory.decodeFile(filePath,options);来进行第一次加载图片,通过outWidth原图的宽度,通过outHeight获取原图的高,接下来通过图片的跨度和控件的高度来获取一个采样率sampleSize,接下来设置inJustDecodeBounds为false,同时设置缩放比,设置inPreferredConfig的图片的图片格式有(分别为ALPHA_8,RGB_565,ARGB_4444,ARGB_8888),最后进行图片的加载.