Android之三大图片缓存原理、特性对比

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


Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用。
 
Picasso 是 Square 开源的项目,且他的主导者是 JakeWharton,所以广为人知。
 
Glide 是 Google 员工的开源项目,被一些 Google App 使用,在去年的 Google I/O 上被推荐,不过目前国内资料不多。
 
Fresco 是 Facebook 在今年上半年开源的图片缓存,主要特点包括:
(1) 两个内存缓存加上 Native 缓存构成了三级缓存
 
(2) 支持流式,可以类似网页上模糊渐进式显示图片
 
(3) 对多帧动画图片支持更好,如 Gif、WebP
 
鉴于 Fresco 还没发布正式的 1.0 版本,同时一直没太多时间熟悉 Fresco 源码,后面对比不包括 Fresco,以后有时间再加入对比。
 

二、基本概念

在正式对比前,先了解几个图片缓存通用的概念:
(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 设计及优点


1. 总体设计及流程
上面是 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。
 
2. 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 设计及优点


1. 总体设计及流程
上面是 Glide 的总体设计图。整个库分为 RequestManager(请求管理器),Engine(数据获取引擎)、 Fetcher(数据获取器)、MemoryCache(内存缓存)、DiskLRUCache、Transformation(图片处理)、Encoder(本地缓存存储)、Registry(图片类型及解析器配置)、Target(目标) 等模块。
 
简单的讲就是 Glide 收到加载及显示资源的任务,创建 Request 并将它交给RequestManager,Request 启动 Engine 去数据源获取资源(通过 Fetcher ),获取到后 Transformation 处理后交给 Target。
 
Glide 依赖于 DiskLRUCache、GifDecoder 等开源库去完成本地缓存和 Gif 图片解码工作。
 
2. 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 功能强大,但代码量大、流转复杂。在较深掌握的情况下才推荐使用,免得出了问题难以下手解决。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/294963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android宿舍管理系统源码,基于android操作系统的手机宿舍管理系统使用手册

《基于android操作系统的手机宿舍管理系统使用手册》由会员分享,可在线阅读,更多相关《基于android操作系统的手机宿舍管理系统使用手册(5页珍藏版)》请在人人文库网上搜索。1、基于an droid操作系统的手机宿舍管理系统使用手册 1 系统概述 本系统是在an…

产品需求文档 PRD

第一轮: 1,文档使用方:UI设计师 2、内容: 根据战略层定义出来产品功能范围, 说明此产品的目的,方便UI设计人员更好的理解产品 产品基本流程 详细的设计框架图,推荐用ax…

他读博期间连发3篇Science,28岁任武大教授后再发Nature!

全世界只有3.14 % 的人关注了爆炸吧知识来源:募格课堂整合自武汉大学、武汉晚报、半月谈等有这样一位学者,读博期间以一作身份发表3篇Science,28岁成为武汉大学化学与分子科学学院教授再发2篇Nature,35岁荣获杰青......今年9月,他…

如何限制并发的 异步IO 请求数量?

咨询区 Grief Coder:我的项目中有下面一段代码:// lets say there is a list of 1000 URLs string[] urls { "http://google.com", "http://yahoo.com", ... };// now lets send HTTP requests to each of these URLs in parallel …

Android之自定义 ActionBar 上的菜单(Menu)文字颜色

本文记录了修改 ActionBar 上 Menu 字体颜色的方法。第一种通过自定义主题实现,第二种通过复写onCreateOptionsMenu实现。 自定义Theme 修改MenuItem 文字颜色 自定义 ActionBar 上的菜单文字颜色需要通过 Activity 的 Theme 实现,而非 ActionBar 的 The…

删除远程桌面登陆痕迹

怎么删除本地远程桌面地址记录(连接地址输入框的下拉菜单)。 首先运行regedit,打开注册表,找到 HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default 右边的那些键值就记录了IP或者域名&…

Java Web开发Tomcat中三种部署项目的方法

第一种方法&#xff1a;在tomcat中的conf目录中&#xff0c;在server.xml中的&#xff0c;<host/>节点中添加&#xff1a; <Context path"/hello" docBase"D:\eclipse3.2.2forwebtools\workspace\hello\WebRoot" debug"0" privileged&q…

Android 页面布局xd,Adobe XD强大的布局系列工具 助你事半功倍

数字设计有多种形式-从移动端、桌面网站到显示屏应用程序、智能助手、车载娱乐系统(例如CarPlay和Android Auto)等等。为当今的应用程序打造数字体验意味着需要针对各种屏幕尺寸、布局和交互类型进行设计。作为设计师&#xff0c;您的时间应该花在用户体验上&#xff0c;而不是…

JS中数组Array的用法{转载}

js数组元素的添加和删除一直比较迷惑&#xff0c;今天终于找到详细说明的资料了&#xff0c;先给个我测试的代码^-^var arr new Array();arr[0] "aaa";arr[1] "bbb";arr[2] "ccc";//alert(arr.length);//3arr.pop();//alert(arr.length);//2…

如果觉得午休时间太短怎么办?

1 假装自己戴了口罩&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 正义不会迟到博主是男的&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 阅读理解有多难&#xff1f;&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 下雨天就不要爬树了&…

Android之ActionBar常用设计和使用总结

常用ActionBar总结 我们经常看见项目的顶部有一些文字显示在中间,或者左边、右边,而且还有一个返回的图标,很方便我们返回,接下来我总结下常用的ActionBar 第一步:写常见的ActionBar的布局文件 我这里写了3个actionbar文件 1、actionbar_return.xml …

WPF 实现温度计

WPF开发者QQ群&#xff1a; 340500857 | 微信群 -> 进入公众号主页 加入组织在WPF中没有现成的温度计控件&#xff0c;所以我们自己实现一个。微信群人数太多入群请添加小编微信号&#xff08;yanjinhuawechat&#xff09;或&#xff08;W_Feng_aiQ&#xff09;邀请入群&am…

100-6

2019独角兽企业重金招聘Python工程师标准>>> /**\第6题&#xff08;数组&#xff09;腾讯面试题&#xff1a; 给你10分钟时间&#xff0c;根据上排给出十个数&#xff0c;在其下排填出对应的十个数 要求下排每个数都是先前上排那十个数在下排出现的次数。 上排的十个…

linux系统644、755、777权限详解

在linux系统中644、755、777三种权限是非常重要的一些权限了&#xff0c;下面我来详细的介绍644、755、777三种权限的使用&#xff0c;希望对各位有帮助。常用的linux文件权限&#xff1a; 444 r--r--r-- 600 rw------- 644 rw-r--r-- 666 rw-rw-rw- 700 rwx------ 744 rwxr--r…

android获取自适应高度,Android中oncreate中获得控件高度或宽度的实现方法

Android中oncreate中获得控件高度或宽度的实现方法onCreate函数只是提供了数据初始化的机会&#xff0c;此时还没有正式绘制图形。在图形尚未渲染的情况下&#xff0c;getWidth()或getHeight()得到的值为0。如果需要自适应屏幕&#xff0c;需要一进入界面就得到父控件大小&…

单例模式7种实现

单例模式 1 、介绍&#xff1a; 单例模式(Singleton)也叫单态模式&#xff0c;是设计模式中最为简单的一种模式&#xff0c;甚至有些模式大师都不称其为模式&#xff0c;称其为一种实现技巧&#xff0c;因为设计模式讲究对象之间的关系的抽象&#xff0c;而单例模式只有自己一…

博导眼里本科生的科研能力:“他们还在玩泥巴”

父母眼中的科学博士&#xff1a;造飞机&#xff0c;造航母&#xff0c;造火箭本科生眼中的科学博士&#xff1a;特严谨&#xff0c;特专业&#xff0c;特……特别老硕士研究生眼中的博士&#xff1a;真能熬&#xff0c;真能写&#xff0c;真坚定博导眼中的博士&#xff1a;还年…

最全前端开发面试问题及答案整理

来自Github秋风的原文 说说你对闭包的理解 Talk about your understanding of closures 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染&#xff0c;缺点是闭包会常驻内存&#xff0c;会增大内存使用量&#xff0c;使用不当很容易造成内存泄露。…

C# 10 新特性 —— 补充篇

C# 10 新特性 —— 补充篇Intro前面已经写了几篇文章介绍 C# 10 新特性的文章&#xff0c;还有一些小的更新Constant interpolated strings在之前的版本中&#xff0c;如果想要使用插值字符串来&#xff0c;则不能声明为一个常量如果依赖于一个常量的插值字符串就只能声明为一个…

线性表的基本操作

#include <stdio.h>#include <stdlib.h>#define OK 1#define ERROR 0//#define INITSIZE 5 //线性表存储空间的初始分配量//#define LISTINCREMENT 1 //线性表存储空间分配增量//实现线性表的顺序存储结构的类型定义typedef int DataType;//线性表的数据类型&#…