Android Universal Image Loader 源码分析(四)

来源:互联网 发布:it技术培训 编辑:程序博客网 时间:2024/05/09 16:53
4.2.21 ImageLoadingInfo.java

加载和显示图片任务需要的信息。
String uri 图片 url。
String memoryCacheKey 图片缓存 key。
ImageAware imageAware 需要加载图片的对象。
ImageSize targetSize 图片的显示尺寸。
DisplayImageOptions options 图片显示的配置项。
ImageLoadingListener listener 图片加载各种时刻的回调接口。
ImageLoadingProgressListener progressListener 图片加载进度的回调接口。
ReentrantLock loadFromUriLock 图片加载中的重入锁。

4.2.22 ImageDownloader.java

图片下载接口。待实现函数

getStream(String imageUri, Object extra)

表示通过 uri 得到 InputStream。
通过内部定义的枚举Scheme, 可以看出 UIL 支持哪些图片来源。

HTTP("http"), HTTPS("https"), FILE("file"), CONTENT("content"), ASSETS("assets"), DRAWABLE("drawable"), UNKNOWN("");
4.2.23 BaseImageDownloader.java

ImageDownloader的具体实现类。得到上面各种Scheme对应的图片 InputStream。

主要函数

(1). getStream(String imageUri, Object extra)

getStream(…)函数内根据不同Scheme类型获取图片输入流。

@Overridepublic InputStream getStream(String imageUri, Object extra) throws IOException {    switch (Scheme.ofUri(imageUri)) {        case HTTP:        case HTTPS:            return getStreamFromNetwork(imageUri, extra);        case FILE:            return getStreamFromFile(imageUri, extra);        case CONTENT:            return getStreamFromContent(imageUri, extra);        case ASSETS:            return getStreamFromAssets(imageUri, extra);        case DRAWABLE:            return getStreamFromDrawable(imageUri, extra);        case UNKNOWN:        default:            return getStreamFromOtherSource(imageUri, extra);    }}

具体见下面各函数介绍。

(2). getStreamFromNetwork(String imageUri, Object extra)

通过HttpURLConnection从网络获取图片的InputStream。支持 response code 为 3xx 的重定向。这里有个小细节代码如下:

try {    imageStream = conn.getInputStream();} catch (IOException e) {    // Read all data to allow reuse connection (http://bit.ly/1ad35PY)    IoUtils.readAndCloseStream(conn.getErrorStream());    throw e;}

在发生异常时会调用conn.getErrorStream()继续读取 Error Stream,这是为了利于网络连接回收及复用。但有意思的是在 Froyo(2.2) 之前,HttpURLConnection 有个重大 Bug,调用 close() 函数会影响连接池,导致连接复用失效,不少库通过在 2.3 之前使用 AndroidHttpClient 解决这个问题。

(3). getStreamFromFile(String imageUri, Object extra)

从文件系统获取图片的InputStream。如果 uri 是 video 类型,则需要单独得到 video 的缩略图返回,否则按照一般读取文件操作返回。

(4). getStreamFromContent(String imageUri, Object extra)

从 ContentProvider 获取图片的InputStream
如果是 video 类型,则先从MediaStore得到 video 的缩略图返回;
如果是联系人类型,通过ContactsContract.Contacts.openContactPhotoInputStream(res, uri)读取内容返回。
否则通过 ContentResolver.openInputStream(…) 读取内容返回。

(5). getStreamFromAssets(String imageUri, Object extra)

从 Assets 中获取图片的InputStream

(6). getStreamFromDrawable(String imageUri, Object extra)

从 Drawable 资源中获取图片的InputStream

(7). getStreamFromOtherSource(String imageUri, Object extra)

UNKNOWN(自定义)类型的处理,目前是直接抛出不支持的异常。

4.2.24 MemoryCache.java

Bitmap 内存缓存接口,需要实现的接口包括 get(…)、put(…)、remove(…)、clear()、keys()。

4.2.25 BaseMemoryCache.java

实现了MemoryCache主要函数的抽象类,以 Map\> softMap 做为缓存池,利于虚拟机在内存不足时回收缓存对象。提供抽象函数:

protected abstract Reference<Bitmap> createReference(Bitmap value)

表示根据 Bitmap 创建一个 Reference 做为缓存对象。Reference 可以是 WeakReference、SoftReference 等。

4.2.26 WeakMemoryCache.java

WeakReference<Bitmap>做为缓存 value 的内存缓存,实现了BaseMemoryCache
实现了BaseMemoryCachecreateReference(Bitmap value)函数,直接返回一个new WeakReference<Bitmap>(value)做为缓存 value。

4.2.27 LimitedMemoryCache.java

限制总字节大小的内存缓存,继承自BaseMemoryCache的抽象类。
会在 put(…) 函数中判断总体大小是否超出了上限,是则循环删除缓存对象直到小于上限。删除顺序由抽象函数

protected abstract Bitmap removeNext()

决定。抽象函数

protected abstract int getSize(Bitmap value)

表示每个元素大小。

4.2.28 LargestLimitedMemoryCache.java

限制总字节大小的内存缓存,会在缓存满时优先删除 size 最大的元素,继承自LimitedMemoryCache
实现了LimitedMemoryCache缓存removeNext()函数,总是返回当前缓存中 size 最大的元素。

4.2.29 UsingFreqLimitedMemoryCache.java

限制总字节大小的内存缓存,会在缓存满时优先删除使用次数最少的元素,继承自LimitedMemoryCache
实现了LimitedMemoryCache缓存removeNext()函数,总是返回当前缓存中使用次数最少的元素。

4.2.30 LRULimitedMemoryCache.java

限制总字节大小的内存缓存,会在缓存满时优先删除最近最少使用的元素,继承自LimitedMemoryCache
通过new LinkedHashMap<String, Bitmap>(10, 1.1f, true)作为缓存池。LinkedHashMap 第三个参数表示是否需要根据访问顺序(accessOrder)排序,true 表示根据accessOrder排序,最近访问的跟最新加入的一样放到最后面,false 表示根据插入顺序排序。这里为 true 且缓存满时始终删除第一个元素,即始终删除最近最少访问的元素。
实现了LimitedMemoryCache缓存removeNext()函数,总是返回第一个元素,即最近最少使用的元素。

4.2.31 FIFOLimitedMemoryCache.java

限制总字节大小的内存缓存,会在缓存满时优先删除先进入缓存的元素,继承自LimitedMemoryCache
实现了LimitedMemoryCache缓存removeNext()函数,总是返回最先进入缓存的元素。

以上所有LimitedMemoryCache子类都有个问题,就是 Bitmap 虽然通过WeakReference<Bitmap>包装,但实际根本不会被虚拟机回收,因为他们子类中同时都保留了 Bitmap 的强引用。大都是 UIL 早期实现的版本,不推荐使用。

4.2.32 LruMemoryCache.java

限制总字节大小的内存缓存,会在缓存满时优先删除最近最少使用的元素,实现了MemoryCache。LRU(Least Recently Used) 为最近最少使用算法。

new LinkedHashMap<String, Bitmap>(0, 0.75f, true)作为缓存池。LinkedHashMap 第三个参数表示是否需要根据访问顺序(accessOrder)排序,true 表示根据accessOrder排序,最近访问的跟最新加入的一样放到最后面,false 表示根据插入顺序排序。这里为 true 且缓存满时始终删除第一个元素,即始终删除最近最少访问的元素。

put(…)函数中通过trimToSize(int maxSize)函数判断总体大小是否超出了上限,是则删除第缓存池中第一个元素,即最近最少使用的元素,直到总体大小小于上限。

LruMemoryCache功能上与LRULimitedMemoryCache类似,不过在实现上更加优雅。用简单的实现接口方式,而不是不断继承的方式。

4.2.33 LimitedAgeMemoryCache.java

限制了对象最长存活周期的内存缓存。
MemoryCache的装饰者,相当于为MemoryCache添加了一个特性。以一个MemoryCache内存缓存和一个 maxAge 做为构造函数入参。在 get(…) 时判断如果对象存活时间已经超过设置的最长时间,则删除。

4.2.34 FuzzyKeyMemoryCache.java

可以将某些原本不同的 key 看做相等,在 put 时删除这些相等的 key。
MemoryCache的装饰者,相当于为MemoryCache添加了一个特性。以一个MemoryCache内存缓存和一个 keyComparator 做为构造函数入参。在 put(…) 时判断如果 key 与缓存中已有 key 经过Comparator比较后相等,则删除之前的元素。

4.2.35 FileNameGenerator.java

根据 uri 得到文件名的接口。

4.2.36 HashCodeFileNameGenerator.java

以 uri 的 hashCode 作为文件名。

4.2.37 Md5FileNameGenerator.java

以 uri 的 MD5 值作为文件名。

4.2.38 DiskCache.java

图片的磁盘缓存接口。

主要函数:

(1) File get(String imageUri)

根据原始图片的 uri 去获取缓存图片的文件。

(2) boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener)

保存 imageStream 到磁盘中,listener 表示保存进度且可在其中取消某些段的保存。

(3) boolean save(String imageUri, Bitmap bitmap)

保存图片到磁盘。

(4) boolean remove(String imageUri)

根据图片 uri 删除缓存图片。

(5) void close()

关闭磁盘缓存,并释放资源。

(6) void clear()

清空磁盘缓存。

(7) File getDirectory()

得到磁盘缓存的根目录。

4.2.39 BaseDiskCache.java

一个无大小限制的本地图片缓存,实现了DiskCache主要函数的抽象类。
图片缓存在cacheDir文件夹内,当cacheDir不可用时,则使用备库reserveCacheDir

主要函数:

(1). save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener)

先根据imageUri得到目标文件,将imageStream先写入与目标文件同一文件夹的 .tmp 结尾的临时文件内,若未被listener取消且写入成功则将临时文件重命名为目标文件并返回 true,否则删除临时文件并返回 false。

(2). save(String imageUri, Bitmap bitmap)

先根据imageUri得到目标文件,通过Bitmap.compress(…)函数将bitmap先写入与目标文件同一文件夹的 .tmp 结尾的临时文件内,若写入成功则将临时文件重命名为目标文件并返回 true,否则删除临时文件并返回 false。

(3). File getFile(String imageUri)

根据 imageUri 和 fileNameGenerator得到文件名,返回cacheDir内该文件,若cacheDir不可用,则使用备库reserveCacheDir

4.2.40 LimitedAgeDiskCache.java

限制了缓存对象最长存活周期的磁盘缓存,继承自BaseDiskCache
在 get(…) 时判断如果缓存对象存活时间已经超过设置的最长时间,则删除。在 save(…) 时保存当存时间作为对象的创建时间。

0 0
原创粉丝点击