Android四大开源图片缓存对比,你的图片你做主

一. 四大图片缓存基本信息

该图是我在网上找的,也许不是最新的,具体的信息以我下边给的为主
为了方便我也就copy了一下,只是希望大家能够看得更清楚:
Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用。
是 Square 开源的项目,且他的主导者是 JakeWharton,所以广为人知。
具体使用:
1:在Application子类中的onCreate方法中初始化ImageLoaderConfiguration

 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)//Picasso 
.threadPriority(Thread.NORM_PRIORITY - 2)//
.denyCacheImageMultipleSizesInMemory()//
.diskCacheFileNameGenerator(new Md5FileNameGenerator())//
.diskCacheSize(50 * 1024 * 1024) // 50 Mb
.memoryCache(new LruMemoryCache(4 * 1024 * 1024)).tasksProcessingOrder(QueueProcessingType.LIFO)//
.writeDebugLogs() // Remove for release app
.build();
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config);

2:再具体的地方使用:

图片加载
  ImageLoader.getInstance().displayImage(data.url, holder.ivIcon);
DisplayImageOptions option = new DisplayImageOptions.Builder()
        .resetViewBeforeLoading(true)
        .cacheOnDisk(true)
        .imageScaleType(ImageScaleType.EXACTLY)
        .bitmapConfig(Bitmap.Config.RGB_565)
        .considerExifParams(true)
        .displayer(new FadeInBitmapDisplayer(300))
        .build();
ImageLoader.getInstance().displayImage(data.url, holder.ivIcon, option);
3:加载各种图片的格式:
String imageUri = "http://site.com/image.png"; // 网络图片  
String imageUri = "file:///mnt/sdcard/image.png"; //SD卡图片  
String imageUri = "content://media/external/audio/albumart/13"; // 媒体文件夹  
String imageUri = "assets://image.png"; // assets  
String imageUri = "drawable://" + R.drawable.image; //  drawable文件 

提供了丰富的缓存策略

内存缓存
现在我们来看Universal-Image-Loader有哪些内存缓存策略
1. 只使用的是强引用缓存 
LruMemoryCache(这个类就是这个开源框架默认的内存缓存类,缓存的是bitmap的强引用,下面我会从源码上面分析这个类)
2.使用强引用和弱引用相结合的缓存有
UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)
LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的弱引用)
FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)
LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)
LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)
3.只使用弱引用缓存
WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收
硬盘缓存
FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)
LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)
TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)
UnlimitedDiscCache(这个缓存类没有任何的限制)

下面我们可以简单的看一下Lru这个到底是如何实现上边的那些缓存的:

S7GX44FE`B7)1V{4@JG6F_S.png

Lru的上边的注解写的很清楚:同时不知道大家有没有注意到Lru使用的LinkHasMap的同时里面传了一个非常重要的参数:

 /**
     * Constructs an empty <tt>LinkedHashMap</tt> instance with the
     * specified initial capacity, load factor and ordering mode.
     *
     * @param  initialCapacity the initial capacity
     * @param  loadFactor      the load factor
     * @param  accessOrder     the ordering mode - <tt>true</tt> for
     *         access-order, <tt>false</tt> for insertion-order
     * @throws IllegalArgumentException if the initial capacity is negative
     *         or the load factor is nonpositive
     */
    public LinkedHashMap(int initialCapacity,
                         float loadFactor,
                         boolean accessOrder) {
        super(initialCapacity, loadFactor);
        this.accessOrder = accessOrder;
    }

LRU是Least Recently Used的缩写,即最近最少使用页面置换[算法,是为虚拟页式存储管理服务的,是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU算法就是将最近最久未使用的页面予以淘汰。
false: 基于插入顺序 true: 基于访问顺序
所以如果有一张图片一直在最地而且一直都未呗使用的话那么他就很好的记录的他的顺利当内存大小不足的直接干掉那张最不常用的图片,说了那么多终于可以说说他的特点了:
其特点:
(1)可以自动检测 adapter 的重用并取消之前的下载
(2)图片变换
(3)可以加载本地资源
(4)可以设置占位资源
(5)支持 debug 模式
Glide介绍:
谷歌为我们介绍了一个名叫 Glide 的图片加载库,。这个库被广泛的运用在google的开源项目中,包括2014年google I/O大会上发布的官方app
下面是谷歌的一段自我解说关于Glide:

Glide is a fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.

简明的来说就是Glide 是一个快速并且高效的android封装库,支持内存缓存和磁盘缓存,
Glide链接地址

Glide的特点:

(1) GIF 动画的解码
(2) 本地视频剧照的解码
(3) 支持缩略图
(4) Activity 生命周期的集成
(5) 转码的支持
(6) 动画的支持
(7) OkHttp 和 Volley 的支持

Glide的最基本使用:

You can download a jar from GitHub's releases page.
Or use Gradle:

repositories { mavenCentral() // jcenter() works as well because it pulls from Maven Central}dependencies { compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.android.support:support-v4:19.1.0'}
// For a simple view:
@Override public void onCreate(Bundle savedInstanceState) {
  ...
  ImageView imageView = (ImageView) findViewById(R.id.my_image_view);

  Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
}

**Fresco **
链接地址
说实话因为的我项目我感觉暂时用不上这么强大的库所以暂时还未用过
不过如果你们想要了解的话这边提供一个链接
具体使用步骤链接
所以我也就不在贴代码展示了
****----___
Fresco 是 Facebook 也是很早开源的图片缓存,主要特点包括:
(1) 两个内存缓存加上 Native 缓存构成了三级缓存
(2) 支持流式,可以类似网页上模糊渐进式显示图片
(3) 对多帧动画图片支持更好,如 Gif、WebP
(4) 我觉得它主要是针对大工程量使用;

二、基本概念

在正式对比前,先了解几个图片缓存通用的概念:
(1) RequestManager:请求生成和管理模块
(2) Engine:引擎部分,负责创建任务(获取数据),并调度执行
(3) GetDataInterface:数据获取接口,负责从各个数据源获取数据。
比如 MemoryCache 从内存缓存获取数据、DiskCache 从本地缓存获取数据,下载器从网络获取数据等。
(4) Displayer:资源(图片)显示器,用于显示或操作资源。
比如 ImageView,这几个图片缓存都不仅仅支持 ImageView,同时支持其他 View 以及虚拟的 Displayer 概念。
(5) Processor 资源(图片)处理器
负责处理资源,比如旋转、压缩、截取等。
以上概念的称呼在不同图片缓存中可能不同,比如 Displayer 在 ImageLoader 中叫做 ImageAware,在 Picasso 和 Glide 中叫做 Target。
三、共同优点
1. 使用简单
都可以通过一句代码可实现图片获取和显示。
2. 可配置度高,自适应程度高
图片缓存的下载器(重试机制)、解码器、显示器、处理器、内存缓存、本地缓存、线程池、缓存算法等大都可轻松配置。
自适应程度高,根据系统性能初始化缓存配置、系统信息变更后动态调整策略。
比如根据 CPU 核数确定最大并发数,根据可用内存确定内存缓存大小,网络状态变化时调整最大并发数等。
3. 多级缓存
都至少有两级缓存、提高图片加载速度。
4. 支持多种数据源
支持多种数据源,网络、本地、资源、Assets 等
5. 支持多种 Displayer
不仅仅支持 ImageView,同时支持其他 View 以及虚拟的 Displayer 概念。
其他小的共同点包括支持动画、支持 transform 处理、获取 EXIF 信息等。
四、ImageLoader 设计及优点

  1. 总体设计及流程
    上面是 ImageLoader 的总体设计图。整个库分为 ImageLoaderEngine,Cache 及 ImageDownloader,ImageDecoder,BitmapDisplayer,BitmapProcessor 五大模块,其中 Cache 分为 MemoryCache 和 DiskCache 两部分。
    简单的讲就是 ImageLoader 收到加载及显示图片的任务,并将它交给 ImageLoaderEngine,ImageLoaderEngine 分发任务到具体线程池去执行,任务通过 Cache 及 ImageDownloader 获取图片,中间可能经过 BitmapProcessor 和 ImageDecoder 处理,最终转换为Bitmap 交给 BitmapDisplayer 在 ImageAware 中显示。

  2. ImageLoader 优点
    (1) 支持下载进度监听
    (2) 可以在 View 滚动中暂停图片加载
    通过 PauseOnScrollListener 接口可以在 View 滚动中暂停图片加载。
    (3) 默认实现多种内存缓存算法这几个图片缓存都可以配置缓存算法,不过 ImageLoader 默认实现了较多缓存算法,如 Size 最大先删除、使用最少先删除、最近最少使用、先进先删除、时间最长先删除等。
    (4) 支持本地缓存文件名规则定义
    五、Picasso 设计及优点

  3. 总体设计及流程
    上面是 Picasso 的总体设计图。整个库分为 Dispatcher,RequestHandler 及 Downloader,PicassoDrawable 等模块。
    Dispatcher 负责分发和处理 Action,包括提交、暂停、继续、取消、网络状态变化、重试等等。
    简单的讲就是 Picasso 收到加载及显示图片的任务,创建 Request 并将它交给 Dispatcher,Dispatcher 分发任务到具体 RequestHandler,任务通过 MemoryCache 及 Handler(数据获取接口) 获取图片,图片获取成功后通过 PicassoDrawable 显示到 Target 中。
    需要注意的是上面 Data 的 File system 部分,Picasso 没有自定义本地缓存的接口,默认使用 http 的本地缓存,API 9 以上使用 okhttp,以下使用 Urlconnection,所以如果需要自定义本地缓存就需要重定义 Downloader。

  4. Picasso 优点
    (1) 自带统计监控功能
    支持图片缓存使用的监控,包括缓存命中率、已使用内存大小、节省的流量等。
    (2) 支持优先级处理
    每次任务调度前会选择优先级高的任务,比如 App 页面中 Banner 的优先级高于 Icon 时就很适用。
    (3) 支持延迟到图片尺寸计算完成加载
    (4) 支持飞行模式、并发线程数根据网络类型而变
    手机切换到飞行模式或网络类型变换时会自动调整线程池最大并发数,比如 wifi 最大并发为 4, 4g 为 3,3g 为 2。
    这里 Picasso 根据网络类型来决定最大并发数,而不是 CPU 核数。
    (5) “无”本地缓存
    无”本地缓存,不是说没有本地缓存,而是 Picasso 自己没有实现,交给了 Square 的另外一个网络库 okhttp 去实现,这样的好处是可以通过请求 Response Header 中的 Cache-Control 及 Expired 控制图片的过期时间。
    六、Glide 设计及优点

  5. 总体设计及流程
    上面是 Glide 的总体设计图。整个库分为 RequestManager(请求管理器),Engine(数据获取引擎)、 Fetcher(数据获取器)、MemoryCache(内存缓存)、DiskLRUCache、Transformation(图片处理)、Encoder(本地缓存存储)、Registry(图片类型及解析器配置)、Target(目标) 等模块。
    简单的讲就是 Glide 收到加载及显示资源的任务,创建 Request 并将它交给RequestManager,Request 启动 Engine 去数据源获取资源(通过 Fetcher ),获取到后 Transformation 处理后交给 Target。
    Glide 依赖于 DiskLRUCache、GifDecoder 等开源库去完成本地缓存和 Gif 图片解码工作。

  6. Glide 优点
    (1) 图片缓存->媒体缓存
    Glide 不仅是一个图片缓存,它支持 Gif、WebP、缩略图。甚至是 Video,所以更该当做一个媒体缓存。
    (2) 支持优先级处理
    (3) 与 Activity/Fragment 生命周期一致,支持 trimMemory
    Glide 对每个 context 都保持一个 RequestManager,通过 FragmentTransaction 保持与 Activity/Fragment 生命周期一致,并且有对应的 trimMemory 接口实现可供调用。
    (4) 支持 okhttp、Volley
    Glide 默认通过 UrlConnection 获取数据,可以配合 okhttp 或是 Volley 使用。实际 ImageLoader、Picasso 也都支持 okhttp、Volley。
    (5) 内存友好
    ① Glide 的内存缓存有个 active 的设计
    从内存缓存中取数据时,不像一般的实现用 get,而是用 remove,再将这个缓存数据放到一个 value 为软引用的 activeResources map 中,并计数引用数,在图片加载完成后进行判断,如果引用计数为空则回收掉。
    ② 内存缓存更小图片
    Glide 以 url、view_width、view_height、屏幕的分辨率等做为联合 key,将处理后的图片缓存在内存缓存中,而不是原始图片以节省大小
    ③ 与 Activity/Fragment 生命周期一致,支持 trimMemory
    ④ 图片默认使用默认 RGB_565 而不是 ARGB_888
    虽然清晰度差些,但图片更小,也可配置到 ARGB_888。
    其他:Glide 可以通过 signature 或不使用本地缓存支持 url 过期
    七、汇总

三者总体上来说,ImageLoader 的功能以及代理容易理解长度都一般。
Picasso 代码虽然只在一个包下,没有严格的包区分,但代码简单、逻辑清晰,一两个小时就能叫深入的了解完。
Glide 功能强大,Glide的源码也是最难理解的,但是如果只是简单使用的还是挺方便的,现在我基本上都是在使用Glide;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容