91

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

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

4

5 回答 5

81

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

Koushik Dutta 的比较主要是针对速度基准。他的帖子只涉及非常基本的东西,并不针对本地图像。在我提出问题后,我想分享我与毕加索和 UIL 的经验。Picasso 和 UIL 都可以加载本地图像。我第一次尝试毕加索并很高兴,但后来我决定切换到 UIL 以获得更多自定义选项。

毕加索:

  • 毕加索流畅的界面很不错。但是随着“with”、“into”、“load”四处跳动,你实际上并不知道幕后是什么。返回的内容令人困惑。

  • Picasso 允许您指定精确的目标尺寸。当您遇到内存压力或性能问题时,它很有用,您可以牺牲一些图像质量来换取速度。

  • 图像在其键中以大小缓存,当您显示不同大小的图像时它很有用。

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

  • Picasso 不会公开对其缓存实例的访问权限。(当您第一次配置毕加索并保留它时,您可以掌握它......)。

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

  • Picasso 在主页上只有几个简单的示例,您必须通读无序的 javadoc 以了解高级用法。

用户界面:

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

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

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

  • UIL 默认在内存中缓存不同大小的图片,可以在配置中关闭。

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

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

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

我建议从 Picasso 开始,如果您需要更多控制和自定义,请选择 UIL。

于 2014-02-28T08:34:46.403 回答
72

如果您阅读Koush 在 G+ 上的这篇文章,您会得到清晰的解决方案来解决您的困惑,我已经总结了这一点,Android-Universal-Image-Loader 是您要求的赢家!

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

新 UIL 版本 (1.9.2) 中即将发生的变化:

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

考虑到所有这些 Android-Universal-Image-Loader 都符合您的要求(加载图像在本地磁盘上)!

于 2013-11-18T09:04:33.163 回答
45

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

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

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

最后,UIL 允许您设置全局图像加载器配置,其中包括选定的磁盘缓存和内存缓存实现和设置以及其他详细信息,但此配置将应用于您的应用程序的任何地方。因此,如果您需要更多的灵活性,例如两个独立的磁盘缓存,那么 UIL 是不行的。另一方面,Volley 允许您拥有任意数量的独立图像加载器,每个都有自己的配置。Picasso 默认使用全局实例,但也允许您构建单独的可配置实例。

总结一下:Picasso 拥有最好的 API,但它使用在所有HttpURLConnection实例之间共享的全局 HTTP 磁盘缓存,这在某些情况下可能过于严格。Volley 具有最佳的性能和模块化,但用户友好性较差,并且需要您编写自己的一两个模块才能使其按您想要的方式工作。总的来说,我会推荐他们都反对 UIL。

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

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

Volley 并没有太大变化,但同时我注意到它有两个问题:

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

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

UIL 仍然很慢(尤其是磁盘缓存),而且它的 API 有经常变化的趋势。

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

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

结论:我现在推荐使用 Picasso + OkHttp,因为它结合了最好的灵活性、API、性能和稳定性。如果你需要 GIF 支持,你也可以考虑 Glide。

于 2014-05-04T23:37:33.313 回答
7

我已经实现了一个应用程序,它应该不断地从互联网上获取和显示图像。我正准备编写一个图像缓存机制,在此之前有朋友向我推荐了通用图像加载器。

UIL 的可定制性非常好。它是如此可定制,以至于新手很容易出错。但是,UIL 在我的应用程序中运行缓慢,并且变得有点慢。我的用例是一个带有图像的 ListView。

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

对我来说,Picasso 绝对是要使用的 API。我对 UIL 的体验并不好。

于 2014-03-07T17:56:41.163 回答
0

我认为 ImageLoader 与 Picasso 库相比更具可定制性和灵活性。

于 2015-07-27T03:25:30.790 回答