Android图片框架对比

一、目的:

对比现在主流图片框架的优势和缺点,在实际项目中如何选择适合自己的框架;
主流框架
Glide、Fresco、Picasso、ImageLoader
共同优点:
使用简单;
可配置度高,自适应程度高;
多级缓存;
支持多种数据源;
丰富的图片格式;
支持多种Displayer(显示目标);
简单对比
Android图片框架对比
Android图片框架对比

二、基本概念

在分析他们的差异、优缺点之前,我们先了解图片缓存通用的概念:
RequestManager:请求生成和管理模块;
Engine:引擎部分,负责创建任务(获取数据),并调度执行;
GetDataInterface:数据获取接口,负责从各个数据源获取数据;
比如:MemoryCache内存缓存获取数据、DiskCache本地缓存获取数据、NetCache下载器从网络获取数据等等;
Displayer:资源显示器,用于显示和操作资源;
比如:ImageView,图片框架缓存不仅仅支持ImageView,同时还要支持其他View以及虚拟的Displayer概念,方便用去扩展自己的需求;
Processor:资源处理器,负责处理资源;
比如:选择、压缩、截取、圆角等处理;
以上概念在不同框架之间可能不同,比如Displayer在ImageLoader中叫做ImageAware,在Picasso和Glide中叫做Target。

三、设计分析

3.1 Glide
Android图片框架对比
Glide设计及流程
以上为Glide的总体设计图。
整个库分为RequestManager(请求管理器)、Engine(数据获取引擎)、Fetcher(数据获取器)、MemoryCache(内存缓存)、DiskLRUCache(本地缓存)、Transformation(图片处理)、Encoder(编码处理)、Registry(图片类型以及解析器配置)、Target(目标)等模块。
简单流程:Glider收到加载及显示资源任务,创建Request并将它交给RequestManager,Request启动Engine去数据源获取资源,得到资源后通过Transformation处理后交给Target.
Glide依赖DiskLRUCache、GifDecoder等开源库去完成本地缓存和Gif图片解密工作
Glide优点
图片缓存->媒体缓存:Glide不仅是一个图片缓存,它支持Gif、WebP、缩略图。甚至是Video,所以更该当做一个媒体缓存。
支持优先级处理
支持Activity、Fragment生命周期一致,支持trimMenory:Glide对每个context都保存一个RequestManager,通过FragmentTransaction保存于Activity、Fragment生命周期一致,并且有对应的trimMemory接口实现可供调用;
支持Okhttp、Volley:Glide默认通过UrlConnection获取数据,可以配合Okhttp或者Volley获取。
内存友好:
①Glide内存缓存有一个active设计
从内存缓存中获取数据时,不像一般实现用get,而是用remove,在将这个缓存数据放到一个value为软引用的activeResources map中,并计数引用数,在图片加载完后进行判断,如果引用数为空则回收掉;
②内存缓存更小图片
Glide以url、view_width、view_height、屏幕分辨率等作为联合key,将处理后图片缓存在内存缓存中,而不是原始图片以节省大小
③图片默认使用RGB_565,而不是ARGB_888;
其他:Glide可以通过signature或不使用本地缓存,支持url过期;
3.2 Picasso
Android图片框架对比
Picasso设计及流程
以上为Picasso的总体设计图。
整个库分为Dispatcher、RequestHandler以及Downloader、PicassoDrawable等模块。
简单流程:Picasso收到加载显示图片任务后,创建Request并将它交给Dispatcher,Dispatcher分发任务到具体RequestHandler,任务通过MemoryCache及Handler(数据获取接口)获取图片,图片获取成功后通过PicassoDrawable显示到Target中;
上面Data的File system部分,Picasso没有自定义本地缓存的接口,默认使用http的本地缓存,API19以上使用okhttp,一下使用UrlConnection,所以如果需要自定义本地缓存就需要自定义Downloader;
Picasso优点
自带统计监控功能:支持图片缓存使用的监控,包括缓存命中率、已使用内存大小、节省的流程等。
支持优先级处理:每次任务调度前会选择优先级高的任务,比如App页面中的Banner的优先级高于Icon时就很适用
支持延时到图片尺寸计算完成加载
支持飞行模式、并发线程数据根据网络类型而变
手机切换到飞行模式或网络类型变换时,会自动调整线程池最大并发数,比如wifi最大并发为4,4G为3,3G为2。
这里Picasso根据网络类型来决定最大并发数,而不是CPU核数。
“无”本地缓存
无本地缓存并不是说没有本地缓存,而是Picasso自己没有实现,交给了Square的另外有一个网络库okhttp去实现,这样的好处是可以通过请求Response Header中的Cache-Control及Expired控制图片的过期时间。
3.3 Fresco
Android图片框架对比
Fresco设计及流程
以上为Fresco的总体设计图
整个库分为UI:DraweeView(View控件)、Drawable(图片数据)、DraweeController(图片控制器)、DraweeHiierarchy(图片体系);Core:DataSource(数据源)、ImagePipeline(图像管道)、Producer(生产者)、ProducerFacotry(生产工厂)、Subcriber(订阅)、Supplier(供应者)、Consumer(消费者);IO/Data:MemoryCache(内存缓存)、Network、DiskCache(磁盘缓存)、Recourse(本地资源)
简单流程:从上面的结构可以看出,fresco主要采用了工厂+建造者的模式实现功能,逻辑划分比较清楚;Fresco框架整体是一个MVC模式,DrawableView—>View用来显示顶层视图、DrawableController—>Control控制加载图片的配置 事件的分发、DrawableHierarchy—>Model 用于存储和描述图片信息,同时也封装了一些图片的显示和视图层级的方法;ImagePipeline模块负责从网络、本地文件系统、本地资源加载图片
Fresco优点
图片的渐进式呈现
良好的内存管理,低端机一样出色
支持动图加载:加载Gif、WebP动图,每一帧都是一张很大的Bitmap,每个动画都有很多帧。Fresco能管理好每一帧并管理好你的内存
丰富的图片处理:缩放、圆角、透明、高斯模糊等处理
支持监听下载事件
一点题外话:
我们有《Android学习、面试;文档、视频资源免费获取》,可复制链接后用石墨文档 App 或小程序打开链接或者私信我资料领取。
https://shimo.im/docs/TG8PDh9D96WGTT8W