您的位置:首页 > 移动开发 > Android开发

android中的bitmap的加载和cache

2017-12-03 23:16 204 查看
Android中目前比较常用的缓存策略是LruCache和DiskLruCache,其中LruCache常被用来做内存缓存,而DiskLruCache常被用作存储缓存。LruCache是Least Recently Used,即最近最少使用算法,这种算法的核心思想是:当缓存快满时,会淘汰近期最少使用的缓存目标。

高效加载Bitmap的核心思想是采用BitmapFactory.Options来加载图片所需要的尺寸。通过BitmapFactory.Options来缩放图片,主要是用到了它的inSampleSize,即采样率。当inSampleSize为1时,采样后的图片大小为图片的原始大小;当insmapleSize大于1时,比如为2,那么采样后的图片(宽高)就是原始图片大小(宽高)的1/2,而像素数为原图的1/4,其内存占有率也为原图的1/4.即采样率必须大于1,图片才会有缩小的效果,即缩放比例为1/(inSampleSize的2次方),有一种特殊情况,当inSampleSize小于1时,其作用相当于1,无缩放效果。

获取采样率的步骤:

1.将BitmapFactory.Options的inJustDecodeBounds参数设置为true并加载图片

2.从BitmapFaction.Options中取出图片的原始宽高信息,他们对应于outWidth和outHeight参数。

3.根据采样率的规则并结合目标View所需要的大小计算出采样率inSmapleSize.

4.将BitmapFactory.Options的inJustDecodeBounds参数设置为false,然后重新加载图片。

注:当将从BitmapFactory.Options读出的参数inJustDecodeBounds设置为true时,BitmapFactory只负责解析图片的原始宽高信息,并不会真正的去加载图片。另外需要注意的是:BitmapFactory获取的图片宽高信息和图片的位置以及程序运行的设备有关。比如一张图片放在不同的drawable目录下或者运行在不同屏幕密度的设备之上,可能会导致BitmapFactory获取到不同的结果。

通常情况下图片缓存时除了在存储设备上存储一份外,还会在内存中存储一份,这是因为从内存中加载图片要比从存储设备上加载图片快,可以提高程序的效率,也提高了用户体验。

缓存策略主要包含缓存的添加、获取和删除三类操作。之所以要进行删除操作是因为不管内存换从还是存储设备缓存,可使用的缓存大小都是有限制的,当缓存容量满了的时候,但是程序还是要继续添加缓存,这时候就需要根据某种策略来删除一些旧的缓存并添加新的缓存。

LruCache是一个泛型类,内部采用一个LinkedHashMap以强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作,当缓存满是,LruCache会移除较早使用的缓存对象,然后再添加新的缓存对象。

强引用:直接的对象引用

软引用:当一个对象只有软引用存在是,系统内存不足时此对象会被GC回收。

弱引用:当一个对象只有弱引用存在时,此对象随时有可能被GC回收。

DiskLruCache:用于实现存储设备缓存即磁盘缓存。通过将缓存对象写入文件系统从而实现缓存效果。

DiskLruCache通过Open方法打开时,会传入一个版本号的东西,如果传入的版本不一致,会情况之前所有的缓存文件,所以需传入固定标识。

DiskLruCache的缓存添加操作是通过Editor完成的,Editor表示一个缓存对象的编辑对象。注意:DiskLruCache不允许同时编辑一个缓存对象。

注意:使用DiskLruCache时,需要做安全校验,即磁盘缓存所需要的大小是否小于磁盘所剩余空间的大小。

在快速滑动列表中使用缓存时需要注意View复用和图片异步加载导致的错位问题,这时候可以通过url去校验是否相等。

列表卡顿原因:有图片时加载网络图片属于耗时操作,用户频繁滑动时会产生较多的异步任务,并发量比较高,造成线程池堵塞,或者瞬间更新UI时并发量也比较高。也会造成卡顿,解决方法是在滑动时不进行图片加载,通过监听onScrollListener的onScrollChanged方法获得滑动状态。也可以通过android:hardwareAccelerated=true为Activity开启硬件加速。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: