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

这是我在 MDCC 上分享的内容(略微改动),也是源码解析第一期发布时介绍的源码解析后续会慢慢做的事。

从总体设计和原理上对几个图片缓存进行对比,没用到他们的朋友也可以了解他们在某些特性上的实现。

上篇关于选择开源项目的好处及如何选择开源项目可见:开源项目使用及选型。

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


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,以后有时间再加入对比。

更多图片缓存库可见:Android 图片缓存库

二、基本概念

在正式对比前,先了解几个图片缓存通用的概念:
(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 功能强大,但代码量大、流转复杂。不过这个是google自家的,推荐使用g

更多图片缓存库可见:Android 图片缓存库

anroid 图片处理加载对比(image loader,Picasso ,glide,fresco)相关推荐

  1. 图片太多加载过慢?学学图片懒加载吧

    实验介绍 我们在浏览图片较多的网页时,有没有想过这些图片是如何成功展示的呢?比如像这样的图片素材网站: 这样的网页拥有成千上万的图片资源,如何优化网页性能成为了开发人员不得不思考的技术问题. 不难发现 ...

  2. next.js 无法导出及导出图片无法加载等问题

    那是因为导入  next/images 问题 建议直接在文件里使用 img 标签 和 图片连接 next.config.js 设置如下: module.exports = {reactStrictMo ...

  3. 悟空活动中台 - 基于 WebP 的图片高性能加载方案

    本文首发于 vivo互联网技术 微信公众号  链接: https://mp.weixin.qq.com/s/rSpWorfNTajtqq_pd7H-nw 作者:悟空中台研发团队 一.背景 移动端网页的 ...

  4. JS无限滚动、回到顶端和图片懒加载

    目录 前言 1 无限滚动(垂直) 1.1 效果和代码 1.2 过程解释 1.2.1 监听页面滚动 1.2.2 获取距页面底部的距离 2 回到顶端 2.1 效果和代码 2.2 过程解释 3 图片懒加载 ...

  5. 前端图片渲染性能优化与实践 — 图片懒加载

    前言 对于图片量比较大的点上首页APP等,在打开商品展示页面的时候需要再加大量图片,在这种场景下如果直接全量加载,必然会造成页面性能消耗过大,白屏或者卡顿,用户体验非常糟糕,用户真的需要我们显示所有图 ...

  6. 可免费阅读各种漫画的微信小程序,内附好用的图片懒加载组件

    一个基于漫画台App原生应用的漫画阅读的微信小程序.所有漫画可免费观看(前提是得有资源?). 项目地址:github源码 API接口文档:API 前言? 在学习一门新的语言或者框架时,做好的方法应该是 ...

  7. 打造自己的图片加载缓存库(Picasso OR Glide)

    好久没写文章了,一个是工作的原因,还一个就是这几个月看了很多文章,一直在补充自己的知识.之前看到一句很喜欢的话--感到快乐就忙东忙西,感到累了就放空自己,这几个月一"快乐"了,就停 ...

  8. Jquery图片懒加载和预加载

    Jquery图片懒加载和预加载 懒加载 1.什么是懒加载 Lazy Load也叫懒加载,延迟加载,顾名思义,就是在图片未到达可视区域时,不加载图片,我们常常在很多的优秀网站上看到类似的例子,例如迅雷. ...

  9. Swift3实现的绘制股票K线库, FastImageCache提升图片的加载和渲染速度,Chameleon颜色框架

    代码1:用Swift3实现的绘制股票K线库 for iOS & macOS 代码地址:网页链接 代码2:FastImageCache是Path团队开发的一个开源库,用于提升图片的加载和渲染速度 ...

最新文章

  1. Effective Java - Item 1: Consider static factory methods instead of constructors
  2. macos big sur安装php扩展_用PHP构建基于swoole扩展的socket服务(附PHP扩展安装步骤)...
  3. java解析xml的三种方法
  4. MATLAB在人工智能中的应用案例:以MATLAB的方式玩转自动驾驶(附部分代码)
  5. 鸟哥的Linux私房菜(基础篇)- Red Hat 6.x旧文件
  6. 配置方法_经济权配置账户与六类经济项——经济权配置方法认识
  7. Oracle发布更新使数据库性能优化达到75%
  8. 台式电脑键盘按键错乱_收藏篇:电脑键盘上的每个按键的作用和命令你都会用么...
  9. Linux远程连接与sshd服务安全设定
  10. 今天有个微信好友咨询我
  11. 引入dubbo项目接口_Dubbo框架的Hello World
  12. 基于ipv6的数据包分析(GNS3)
  13. 创建Docker私有仓库
  14. thinkphp5 mysql加1_ThinkPHP5.1的数据库链接和增删改查
  15. 将网站转换为应用程序的软件—“Unite”
  16. 深圳计算机软考培训哪家好,深圳计算机软考——信息系统项目管理报名培训
  17. VoIP技术应用中存在的问题的分析研究
  18. DXP改变字体的方法
  19. 共享充电步入“大三元”时代,三电一兽们吃得饱吗?
  20. HiveSQL一天一个小技巧:如何借助于str_to_map进行行转列

热门文章

  1. win7下python的安装与配置_Win7下Python与Tensorflow-CPU版开发环境的安装与配置过程...
  2. 如何扩大临linux零时空间,手把手教你如何扩充linux系统空间
  3. linux nginx cdn,linux – Nginx Proxy_Pass到CDN与直接击中CDN. P...
  4. 构造先存储再计算的加法器电路
  5. mybatis insert 返回主键_面试准备季——MyBatis 面试专题(含答案)
  6. Oralce的图形化界面----plsql developer涉及到的知识点总结
  7. android 分段显示百分比,按百分比设置排名-Android DisplayMetrics
  8. C++引用不能绑定到临时数据
  9. Ubuntu 安装redis desktop manager
  10. mysql的单行注释_MySQL基础--会这些就够了