文档章节

Android Universal Image Loader 源码分析(四)

k
 kim366
发布于 2016/05/13 19:15
字数 2178
阅读 2
收藏 0
点赞 2
评论 0
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类型获取图片输入流。

@Override
public 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(…) 时保存当存时间作为对象的创建时间。

本文转载自:http://blog.csdn.net/oyangyujun/article/details/47419961

共有 人打赏支持
k
粉丝 1
博文 129
码字总数 0
作品 0
朝阳
android沉浸状态栏实现、地图多线路规划、Retrofit+RxJava+Jsoup+Mvp模式资讯类App等源码

Android精选源码 Android各种沉浸式状态栏实现源码(http://www.apkbus.com/thread-598927-1-1.html) Android自定义View实现炫酷的星期日期选择控件源码(http://www.apkbus.com/thread-59893...

逆鳞龙 ⋅ 05/08 ⋅ 0

Glide ‘优’ 与 ‘愁’

随着业务的增长,加载图片是不可避免的需求。从一开始的自己写一个 ImageLoader 到井喷似的第三方图片加载库,当然中间还时不时穿插着 asynctask ,三级缓存,LRU Cache等。那个时候想必大家...

IMSk ⋅ 06/20 ⋅ 0

android高仿抖音、点餐界面、天气项目、自定义view指示、爬取美女图片等源码

Android精选源码 一个爬取美女图片的app(http://www.apkbus.com/thread-600077-1-1.html) Android高仿抖音(http://www.apkbus.com/thread-600081-1-1.html) android一个可以上拉下滑的Ui效果......

逆鳞龙 ⋅ 06/12 ⋅ 0

android仿IT之家、炫酷水波纹、Kotlin MVP项目、后台模拟点击、蜂巢迷宫小游戏等源码

Android精选源码 Android 炫酷的多重水波纹源码(http://www.apkbus.com/thread-598586-1-1.html) Android开发一款基于行为识别和个性化推荐的智能推荐APP(http://www.apkbus.com/thread-5985...

逆鳞龙 ⋅ 05/02 ⋅ 0

Android 使用Universal Image Loader绘制带圆角的图片(一)

Android 使用Universal Image Loader绘制带圆角的图片(一) 绘制带圆角的控件难吗?貌似不难。对于一个普通layout或者widget,要绘制圆角,只要把 background设置成下面这样的drawable就行了...

yhchinabest ⋅ 2015/07/20 ⋅ 0

Android APP打开另一个APP完整逻辑实现

本文出自:https://blog.csdn.net/DT235201314/article/details/80255143 一丶概述 前段时间配合开发,完成了一个APP拉起另一个APP的需求,负责接收数据跨登录部分。当然整个实现思路挺感兴趣...

天一方蓝 ⋅ 05/10 ⋅ 0

android蓝牙手柄、仿QQ看房、仿慕课网、数据库二维码框架等源码

Android精选源码 可自定义图片指示器并支持自定义Tab宽度的TabLayout源码(http://www.apkbus.com/thread-599243-1-1.html) android蓝牙控制手柄操作源码(http://www.apkbus.com/thread-59928...

逆鳞龙 ⋅ 05/15 ⋅ 0

android开发常用工具类、高仿客户端、附近厕所、验证码助手、相机图片处理等源码

Android精选源码 android开发过程经常要用的工具类源码(http://www.apkbus.com/thread-599826-1-1.html) Android类似QQ空间个人主页下拉头部放大的布局效果(http://www.apkbus.com/thread-5...

逆鳞龙 ⋅ 05/29 ⋅ 0

[原创] 浅谈开源项目Android-Universal-Image-Loader(Part 3.1)

  最近,总算有时间去做些平时喜欢而没空去做的事情。一直觉得项目中使用的Image Loader适用性不强,昨晚在github随便逛逛,发现一个开源项目Android-Universal-Image-Loader十分火热。代码...

笨鸟不乖 ⋅ 2016/01/06 ⋅ 1

android仿摩拜单车APP、炫酷RecyclerView、卡片滑动、仿饿了么点餐、自定义索引等源码

Android精选源码 Android自定义索引源码(http://www.apkbus.com/thread-599163-1-1.html) LayoutManager实现的卡片滑动(http://www.apkbus.com/thread-599396-1-1.html) android仿摩拜单车A......

逆鳞龙 ⋅ 05/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Kubeflow实战系列:利用TFJob导出分布式TensorFlow模型

介绍 本系列将介绍如何在阿里云容器服务上运行Kubeflow, 本文介绍如何使用TfJob导出分布式模型训练模型。 第一篇:阿里云上使用JupyterHub 第二篇:阿里云上小试TFJob 第三篇:利用TFJob运行...

全部原谅 ⋅ 1分钟前 ⋅ 0

007. 深入JVM学习—老年代

老年代空间的主要目的是用于存储由Eden发送来的对象,一般在经历好几次“Minor GC”还会保存下来的对象,才会被复制到老年代,这样就可以存放更多的对象,同时在老年代中执行GC的次数也相对较...

影狼 ⋅ 2分钟前 ⋅ 0

常见的一些C#开源框架或者开源项目

原:https://blog.csdn.net/qq_27825451/article/details/70666044 Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更......

whoisliang ⋅ 3分钟前 ⋅ 0

设计模式基本原理

刚开始接触编程这行的时候看过设计模式,当时感觉学这些模式没有太大的用处,当时也看不太懂。但是随着慢慢接触这一行,经过一段时间的编程以后,再回过头来看设计模式,发现设计模式的确是太...

王子城 ⋅ 6分钟前 ⋅ 0

阿里云全面支持IPv6!一文揽尽4位大咖精彩演讲

摘要: 自从去年11月以来,阿里巴巴高度重视数据中心的网络改造、云产品改造、应用及网络改造等多个维度,经过半年以来的建设,阿里云已经完成了域名解析等关键产品的分析,现在阿里云已经完...

传授知识的天使 ⋅ 17分钟前 ⋅ 0

windows Android sdk 配置

1、下载Android SDK,点击安装,直接默认路径即可! 下载地址:http://developer.android.com/sdk/index.html 2、默认路径安装后,安装完成,开始配置环境变量。 3、打开计算机属性——高级系...

阿豪boy ⋅ 19分钟前 ⋅ 0

bash shell script 简明教程

User <--> bash <--> kernel shell is not kernel or part of kernel various shells: tcsh, csh, bash, ksh find the using shell: echo $SHELL find all the shells: cat /etc/shells what......

mskk ⋅ 22分钟前 ⋅ 0

Service Mesh简史

William Morgan Service Mesh是一个相当新的概念,讲它的“历史”似乎有些勉强。就目前而言,Service Mesh已经在部分企业生产环境中运行了超过18个月,它的源头可以追溯到2010年前后互联网公...

好雨云帮 ⋅ 22分钟前 ⋅ 0

10个免费的服务器监控工具

监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的。你要确保用户始终可以打开你的网站并且网速不慢。服务器监控工具允许你收集和分析有关你的Web服务器的数据。 有许多非常好的服...

李朝强 ⋅ 34分钟前 ⋅ 0

压缩工具之zip-tar

zip 支持目录压缩。使用yum安装zip包,使用yum安装unzip包 zip 1.txt.zip 1.txt #将1.txt文件压缩,新生成的压缩文件为1.txt.zip,原文件保留 zip -r 123.zip 123/ #-r对目录操作。将123/目录...

ZHENG-JY ⋅ 35分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部