适用于Android的本地图像缓存解决方案:Square Picasso,Universal Image Loader,Glide,Fresco?


89

我正在寻找Android中的异步图像加载和缓存库。我本打算使用Picasso,但是我发现Universal Image Loader在GitHub上更受欢迎。有人知道这两个库吗?优点和缺点的摘要将是很好的。

(我所有的图像都在本地磁盘上,因此我不需要联网,因此我认为Volley不适合)

Answers:


80

2018年9月更新:几年后,我需要一个几乎相同的东西用于本地图像缓存解决方案。这次,UIL尚未积极开发。我比较了流行的库,结论很简单:只使用Glide。它更加强大和可配置。多年前,我不得不分叉并对UIL进行更改。Glide在缓存策略和使用自定义键的多级分辨率缓存方面支持我的所有用例。只需使用Glide!

Koushik Dutta的比较主要是针对速度基准。他的帖子仅涉及非常基本的内容,并且不专门针对本地图像。问了问题之后,我想与我分享Picasso和UIL的经验。毕加索和UIL均可加载本地图像。我最初尝试使用Picasso感到很高兴,但后来我决定改用UIL以获得更多自定义选项。

毕加索:

  • 毕加索的流利界面很好。但是,随着“ with”,“ into”,“ load”跳来跳去,您实际上不知道背后是什么。返回的结果令人困惑。

  • 毕加索可让您指定确切的目标尺寸。当您遇到内存不足或性能问题时,此功能很有用,您可以权衡某些图像质量以提高速度。

  • 图像缓存有其键大小,这在显示不同大小的图像时很有用。

  • 您可以自定义内存缓存大小。但是它的磁盘缓存仅用于http请求。对于本地图像,如果您关心加载速度,最好有一个缩略图磁盘缓存,这样您就不必每次都读取一张图像的几MB。毕加索没有此机制来调整缩略图大小并将其保存在磁盘上。

  • Picasso不会公开对其缓存实例的访问。(在首次配置Picasso并保留它时,您可以保留它。)。

  • 有时您想异步将图像读入侦听器返回的位图。令人惊讶的是,毕加索没有。“ fetch()”不会传递任何东西。“ get()”用于同步读取,“ load()”用于异步绘制视图。

  • 毕加索的首页上只有几个简单的示例,您必须通读无序的Javadoc以获得高级用法。

UIL:

  • UIL使用构建器进行定制。几乎所有内容都可以配置。

  • UIL不允许您指定要加载到视图中的大小。它根据视图的大小使用一些规则。它不如毕加索灵活。我无法加载较低分辨率的图像以减少内存占用。(编辑:可以通过在源代码中添加ImageSize参数并绕过视图大小检查来轻松修改此行为)

  • UIL提供可自定义的光盘缓存,您可以使用它来缓存具有指定大小的缩略图。但这并不完美。这是细节。(编辑:如果您关心速度,并且想要多级缩略图缓存,例如我的情况,则可以修改源代码,让磁盘缓存使用“ memoryKey”,并使它也对大小敏感)

  • 默认情况下,UIL将不同大小的图像缓存在内存中,并且可以在配置中将其关闭。

  • UIL公开了您可以访问的后备内存和磁盘缓存。

  • UIL提供了获取位图或加载到视图的灵活方式。

  • UIL在文档方面更好。UIL在Github页面上提供了详细的用法,并且有一个链接的教程。

我建议从毕加索开始,如果您需要更多控制和自定义,请使用UIL。


我实际上被卡在了两者之间...从本质上来说,我将从服务器中存储的图像中恢复图像,因此通过http调用,然后将其存储以进行缓存(缩略图和常规尺寸,我可能会存储两种尺寸都在我的目录中)...毕加索是走的路吗?
Lion789

@ Lion789 Picasso仅对本地文件执行本地内存缓存,并且它使用HttpResponseCache进行网络磁盘缓存,您必须对此进行研究。UIL具有可配置的磁盘缓存,您可以进行一些小的更改以使其接受不同大小的图像/缩略图。也许先尝试毕加索,如果您发现它太有限了,请使用UIL进行自定义
XY

因此,毕加索可以加载较小的图像!然后,我不必加载8兆像素的像素!谢谢,你帮了我!
Aron Lorincz 2014年

你能回答这个问题吗? stackoverflow.com/questions/35433895/...
乌斯曼蛙

UIL does not allow you to specify the size you want to load into a view是不是100%正确..您可以使用UILpublic void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener)
Martin Mlostek

72

如果您阅读Koush在G +上发布的这篇文章,将会为您的困惑找到清晰的解决方案,我在此进行了总结,因为Android-Universal-Image-Loader是您要求的赢家!

  • 如果您使用网络,则毕加索具有最好的图像API!

  • UrlImageViewHelper + AndroidAsync是最快的。然而,与另外两个很棒的库一起玩耍确实突出了图像API的过时之处。

  • 凌空抽射。我真的很喜欢他们的可插入后端传输,
    并且可能最终将AndroidAsync放在那里。请求优先级
    和取消管理很棒(如果您使用网络)

  • Android-Universal-Image-Loader是目前最流行的一种
    。高度可定制的。

该项目旨在为异步图像加载,缓存和显示提供可重用的工具。它最初基于Fedor Vlasov的项目,从那时起经过了巨大的重构和改进。

新的UIL版本(1.9.2)中即将进行的更改:

可以通过UI线程调用ImageLoader新磁盘缓存API(更灵活)。基于Jake Wharton的DiskLruCache的新LruDiscCache。

考虑到所有这些Android-Universal-Image-Loader套件,您的要求(将图像加载到本地磁盘上)!


尽管一切都已完全实现,但我还是从Picasso开始,然后结束了向Universal的切换。毕加索(Picasso)具有更好的api界面,但也存在许多问题。是棺材里最后的钉子。
Lisandro

45

我想与我分享这三个库的经验:UIL,毕加索和Volley。我以前使用过UIL,但后来得出的结论是我不能真正推荐它,而是建议使用Volley或Picasso,它们都是由才华横溢的团队开发的。UIL一点也不差,但它缺少对其他两个库细节的关注。

我发现UIL的UI性能不太好。它比Volley或Picasso更倾向于锁定UI线程。这可能部分是由于以下事实:UIL不支持批处理图像响应,而Picasso和Volley默认情况下会这样做。

另外,我不喜欢UIL的磁盘缓存系统。虽然可以各种实现之间进行选择,我需要指出的是,目前没有办法限制UIL磁盘缓存按总规模,并通过实体过期时间。Volley和Picasso这样做,它们默认使用服务器返回的过期时间,而UIL忽略它。

最后,UIL允许您设置全局图像加载器配置,其中包括选定的磁盘高速缓存和内存高速缓存实现以及设置和其他详细信息,但是此配置将在应用程序中的所有位置应用。因此,如果您需要更大的灵活性,例如两个单独的磁盘缓存,那么UIL绝对不行。另一方面,Volley允许您根据需要拥有多个独立的图像加载器,每个图像加载器都有自己的配置。毕加索默认情况下使用全局实例,但也允许您构建单独的可配置实例。

总结一下:毕加索具有最好的API,但它使用所有HttpURLConnection实例之间共享的全局HTTP磁盘缓存,在某些情况下可能限制太多。Volley具有最佳的性能和模块化,但对用户的友好度较低,并且需要您编写一个或两个自己的模块才能使其按需工作。总的来说,我建议他们两个都反对UIL。

编辑(2014年12月18日):自从我写了这个最初的答案以来,事情发生了变化,我觉得有必要改进它:

Picasso 2.4的配置比以前的版本还要好,并且与OkHttp一起使用(强烈建议使用)时,它还可以为每个实例使用单独的磁盘缓存,因此您的操作实际上没有任何限制。更重要的是,我注意到Picasso和OkHttp的性能有了很大的提高,我认为它现在是Android上最快的图像加载器解决方案。请注意,在我的代码中,我总是.fit().centerCrop()或结合使用.centerInside()以降低内存使用率,并避免在UI线程上调整位图的大小。毕加索积极开发并提供支持,这无疑是一大优势。

排球并没有太大的改变,但与此同时我注意到了两个问题:

  • 有时在高负载下,由于某些磁盘缓存损坏,不再加载某些映像。
  • 与您从其他库中获得的缩略图相比,NetworkImageView中显示的缩略图(缩放比例类型设置为centerCrop)非常模糊。

由于这些原因,我决定停止使用Volley。

UIL仍然很慢(尤其是磁盘缓存),并且它的API经常更改。

我还测试了这个名为Glide 3的新库,声称它比使用Picasso类API的Picasso更加优化。根据我的个人经验,即使在与OkHttp结合使用时,在重负载的网络请求中它实际上也比Picasso和Volley慢。更糟糕的是,离开活动时,它导致我的Lollipop下的应用崩溃。与竞争对手相比,它仍然具有2个优势:

  • 它支持动画GIF解码
  • 它将最终缩小的位图放入磁盘缓存中,这意味着从磁盘缓存中进行读取非常快。

结论:我现在建议使用Picasso + OkHttp,因为它可以提供最佳的灵活性,API,性能和稳定性。如果您需要GIF支持,也可以考虑使用Glide。


1
为了解决关于UIL的最后一点,您可以根据需要创建尽可能多的不同ImageLoader类和配置。您只需要对该ImageLoader类进行子类化。看到这里:github.com/nostra13/Android-Universal-Image-Loader/issues/…– TalkLittle 2014
6

看起来像骇客,但感谢您的提示,很高兴知道。
BladeCoder 2014年

3
不能说我同意这种观点,我们在这里使用毕加索,我的相册中有500幅以上的高分辨率图像,并且遇到了性能和内存问题,尝试了UIL并立即解决了问题。这是一个最小的样本,隔离了我们所遇到的问题。
HaMMeReD 2014年

如果您要显示分辨率比屏幕高得多的图像或高分辨率图像的许多缩略图,则绝对应该对它们进行下采样。我认为UIL自动执行此操作,如果您未指定正确的选项,则Picasso不会执行此操作,因此会出现内存问题。我个人更喜欢在Volley中使用NetworkImageView,它是一个小部件,可以将加载的图像降采样为自己的大小。
BladeCoder 2014年

在UIL中,如果我们不想更改或对特定图像进行其他处理,则可以使用DisplayImageOptions类。
Rahul Rastogi 2014年

7

我实现了一个应不断获取并显示来自互联网的图像的应用程序。我打算对图像缓存机制进行编程,然后一个朋友向我推荐了通用图像加载器。

UIL是非常好的可定制的。它是如此可定制的,因此新手可以轻松地做出错误的事情。但是,UIL在我的应用程序中很慢,并且变慢了一点。我的用例是带有图像的ListView。

昨天我正在寻找UIL的替代品,然后我发现了毕加索。毕加索易于集成和使用:Just Picasso.context(context).load(url).into(imageview)和图像可以更快,更流畅地集成。

对我来说,毕加索绝对是要使用的API。我对UIL的体验不好。


对于未来的读者:Glide比毕加索更好。看看
therealprashant

0

与Picasso库相比,我认为ImageLoader更具自定义性和灵活性。


8
怎么样?稍微解释会有所帮助。
达尔潘
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.