【问题标题】:Comparison of Android networking libraries: OkHTTP, Retrofit, and Volley [closed]Android 网络库的比较:OkHTTP、Retrofit 和 Volley [关闭]
【发布时间】:2025-12-05 06:10:02
【问题描述】:

一位学习 Android 的 iOS 开发人员提出的两部分问题,他正在开发一个 Android 项目,该项目将提出各种请求,从 JSON 到图像再到音频和视频的流式下载:

  1. 在 iOS 上,我广泛使用了 AFNetworking 项目。是否有适用于 Android 的等效库?

  2. 我已经阅读了 Square 的 OkHTTPRetrofit 以及 Volley,但还没有与他们一起开发的经验。我希望有人可以为每个人提供一些最佳用例的具体示例。根据我的阅读,OkHTTP 似乎是三者中最健壮的,并且可以处理这个项目的要求(如上所述)。

【问题讨论】:

  • 如果您使用 HttpUrlConnection 的内部实现,您应该考虑到 HttpUrlConnection 对 POST 请求使用静默重试。这对我造成了很大的伤害。欲了解更多信息,请阅读此处:*.com/a/37675253/2061089
  • 如果有人需要所有网络库的列表,您可以在我的博文androidredman.wordpress.com/2017/06/26/…中找到它
  • Volley 可以运行传统的 Apache、HttpUrlConnection、Apache-4 或 OkHttp。 Retrofit 在哪里真的只运行 OkHttp。改造更容易配置。

标签: android networking retrofit android-networking


【解决方案1】:

我希望有人可以为每个人提供一些最佳用例的具体示例。

如果您正在与 Web 服务通信,请使用 Retrofit。如果您正在下载图像,请使用对等库 Picasso。如果您需要执行 Retrofit/Picasso 之外的 HTTP 操作,请使用 OkHTTP。

Volley 与 Retrofit + Picasso 大致竞争。从好的方面来说,它是一个图书馆。不利的一面是,它是 一个未记录的, 一个不受支持的“将代码扔到墙上并在其上进行 I|O 演示”的库。

编辑 - Volley 现在得到 Google 的正式支持。请参考Google Developer Guide

根据我的阅读,OkHTTP 似乎是 3 个中最健壮的

如果可用,Retrofit 会自动使用 OkHTTP。有一个Gist from Jake Wharton 将 Volley 连接到 OkHTTP。

并且可以处理这个项目的要求(如上所述)。

按照“流式传输”的传统定义,您可能不会将它们用于“音频和视频的流式下载”。相反,Android 的媒体框架会为您处理这些 HTTP 请求。

话虽如此,如果您要尝试进行自己的基于 HTTP 的流式传输,OkHTTP 应该可以处理这种情况;我不记得 Volley 会如何处理这种情况。 Retrofit 和 Picasso 都不是为此而设计的。

【讨论】:

  • 感谢@CommonsWare 的简明回答,以及关于 Volley 无证 steez 的注释(得到了这样的印象,尤其是与其他项目相比)。绝对可以帮助我把事情做好。
  • @CommonsWare 的另一个很好的回答。有人可以跟进 RoboSpice 如何融入所有这些吗?
  • @user1923613 github.com/octo-online/robospice 如果您使用 volley 进行网络调用,则无需使用 robospice!,volley 完成了 Robospice 为网络调用所做的许多事情,Robospice 开箱即用地支持 REST (使用 Spring Android 或 Google Http Client 或 Retrofit)。如果您想通过强大的网络客户端快速联网和图像加载,您可以选择 volley!但是您可以替换使用 Robospice 的普通 android 异步任务以获得更好的性能并避免内存泄漏!
  • @frostymarvelous:我觉得无证和不受支持的理由绰绰有余。谷歌并不是缺少一个系统来更正式地处理这样的事情(例如,Android 支持库)。在这个答案之后的两年里,从好的方面来说,有一些社区支持,包括将一些非官方的代码打包成一个工件。
  • @AbhinavVutukuri:您正在评论两年多前的答案。当时还没有文档。
【解决方案2】:

从 Volley 的角度来看,这里有一些满足您要求的优势:

一方面,Volley 完全专注于处理单个的小型 HTTP 请求。因此,如果您的 HTTP 请求处理有一些怪癖,Volley 可能会为您提供一个钩子。另一方面,如果您在图像处理方面有一个怪癖,那么唯一真正的钩子就是 ImageCache。 “这不是什么都没有,但也不是很多!”。但它还有更多其他优点,例如一旦定义了请求,就可以在片段或活动中使用它们,这与并行 AsyncTask 不同

Volley 的优缺点:

那么 Volley 有什么好处呢?

  • 网络部分不仅仅用于图像。排球的目的是 后端的一个组成部分。对于一个基于 简单的 REST 服务,这可能是一个巨大的胜利。

  • NetworkImageView 在请求清理方面比 Picasso,并且在其 GC 使用模式上更加保守。 NetworkImageView 完全依赖于强内存引用,并且 一旦对 ImageView,或者只要 ImageView 移出屏幕。

  • 性能。这篇文章不会评估这种说法,但他们已经清楚 在他们的内存使用模式上采取了一些谨慎的态度。 Volley 还努力批量回调到主线程以 减少上下文切换。

  • Volley 显然也有未来。如果您是,请查看 RequestFuture 有兴趣。

  • 如果您正在处理高分辨率压缩图像,Volley 是 这里唯一有效的解决方案。

  • Volley 可以与 Okhttp 一起使用(新版本的 Okhttp 支持 NIO 以获得更好的性能)

  • Volley 在 Activity 生命周期中表现出色。

排球问题:
由于 Volley 是新的,因此尚不支持一些东西,但它已修复。

  1. 多部分请求(解决方案:https://github.com/vinaysshenoy/enhanced-volley

  2. 状态码 201 被视为错误,状态码 200 到 207 现在是成功响应。(固定:https://github.com/Vinayrraj/CustomVolley

    更新:在最新版本的 Google volley 中,2XX 状态码错误现在是 fixed!感谢 Ficus Kirkpatrick!

  3. 文档较少,但很多人在 github 中支持 volley,可以在 here 找到类似 java 的文档。 在 android 开发者网站上,您可以找到Transmitting Network Data Using Volley 的指南。并且volley源码可以在Google Git

  4. 找到
  5. 要解决/更改Redirect Policy of Volley 框架使用Volley with OkHTTP(上面提到的CommonsWare)

你也可以阅读这个Comparing Volley's image loading with Picasso

改造:

它由Square 发布,它提供了非常易于使用的 REST API(更新:瞧!支持 NIO)

改造的优点:

  • 与 Volley 相比,Retrofit 的 REST API 代码简洁,并提供 优秀的 API 文档,并在社区中有很好的支持! 添加到项目中非常容易。

  • 我们可以将它与任何带有错误处理的序列化库一起使用。

更新: - Retrofit 2.0.0-beta2 有很多非常好的变化

  • Retrofit with OkHttp 2.0 的 1.6 版现在依赖于 Okio 来支持 java.iojava.nio 这使得它使用 ByteStringBuffer 可以更轻松地访问、存储和处理您的数据,以做一些聪明的事情来节省 CPU 和内存。 (仅供参考:这让我想起了支持 NIO 的 Koush's OIN 库!) 我们可以使用Retrofit together with RxJava 来组合和链接REST 调用,使用rxObservables 来避免丑陋的回调链(避免回调地狱!!)

1.6 版改造的缺点:

  • 与内存相关的错误处理功能不好(在旧版本的 Retrofit/OkHttp 中)不确定它是否通过支持 Java NIO 的 Okio 得到了改进。

  • 如果我们使用这个,最小的线程辅助可能会导致回调地狱 以不正当的方式。

(以上所有Cons都已在新版Retrofit 2.0 beta中解决)

================================================ ==========================

更新:

Android Async vs Volley vs Retrofit 性能基准(毫秒,值越低越好):

(仅供参考,Retrofit Benchmarks 信息将通过 java NIO 支持得到改进,因为新版本的 OKhttp 依赖于 NIO Okio 库)

在所有三个重复次数不同(1 到 25 次)的测试中,Volley 速度从 50% 到 75% 不等。改造以令人印象深刻的速度进行 比 AsyncTask 快 50% 到 90%,到达相同的端点 相同的次数。在仪表板测试套件上,这已翻译 更快地加载/解析数据几秒钟。这是一个 巨大的现实世界差异。为了使考试公平, AsyncTasks/Volley 的时间包括 JSON 解析,就像 Retrofit 一样 它会自动为您服务。

RetroFit 在基准测试中获胜!

最后,我们决定为我们的应用程序使用 Retrofit。不是 只是速度快得离谱,但它与我们的 现有架构。我们能够进行父回调 自动执行错误处理、缓存和 分页对我们的 API 几乎没有任何努力。为了融入 改造,我们必须重命名我们的变量以使我们的模型 GSON 合规,写几个简单的接口,删除函数 旧 API,并修改我们的片段以不使用 AsyncTasks。现在我们 有几个片段完全转换,这很无痛。那里 是一些成长的痛苦和我们必须克服的问题,但是 总体来说进展顺利。一开始,我们遇到了几个 技术问题/错误,但 Square 有一个很棒的 Google+ 社区 这能够帮助我们度过难关。

什么时候使用 Volley?!

当我们需要加载图像以及使用 REST API 时,我们可以使用 Volley!,网络调用队列系统需要同时处理许多 n/w 请求! Volley 也比 Retrofit 有更好的内存相关错误处理!

OkHttp可以和Volley一起使用,Retrofit默认使用OkHttp!它具有SPDY 支持、连接池、磁盘缓存、透明压缩!最近,它通过 Okio 库获得了对 java NIO 的一些支持。

来源,来源:volley-vs-retrofit Josh Ruesch 先生

注意:关于流媒体,这取决于您想要的流媒体类型,例如 RTSP/RTCP。

【讨论】:

  • @Jan1337z +1 获取信息!我已经更新了!android.googlesource.com/platform/frameworks/volley
  • @LOG_TAG 在您的示例中对 RoboSpice 进行基准测试会很有趣。我们甚至提供了一个改造模块,所以我相信这需要很少的改动。来源在某处可用吗? RS 的优点是可以正确处理执行网络请求的活动的生命周期,并且我们还提供透明缓存,我想与纯粹的改造请求相比开销会很小。
  • @Snicolas 我得到了 Josh Ruesch blog 的基准测试结果,您可以看到 Ficus Kirkpatrick(Volley 创始人)和 Josh Ruesch 之间的转换!他还没有在任何地方共享基准测试项目!仅供参考,我刚刚开始学习您的 RoboSpice with retrofit sample 面对此通知 issue :)
  • 嗨!关于 Volley 的 Multipart Requests,我认为我们可以在 httpmime 库中使用 MultipartEntityBuilder
  • 有其他人验证过这些基准吗?由于 M 中不推荐使用 apache http 库(并且我将它用于多部分构建器),我决定将我的网络代码迁移到 Retrofit。我最初更改了一个 GET 调用以从服务器获取一堆对象。我对 Retrofit 与 AsyncTask 进行了计时(使用我自己的 JSON 解析)。性能非常接近,而不是表的“一次讨论”列中显示的 3 倍改进。诚然,生成的代码更简洁,我不必编写自己的 JSON 解析器,但对于单个 GET 请求,改进并不存在。
【解决方案3】:

RoboSpice 对比。凌空抽射

来自https://groups.google.com/forum/#!topic/robospice/QwVCfY_glOQ

  • RoboSpice(RS) 是基于服务的,比 Volley 更尊重 Android 理念。 Volley 是基于线程的,这不是在 Android 上进行后台处理的方式。最终,您可以深入挖掘这两个库并发现它们非常相似,但我们进行后台处理的方式更面向 Android,例如,它允许我们告诉用户 RS 实际上在后台做某事,这将是凌空抽射很困难(实际上一点也不)。
  • RoboSpice 和 volley 都提供了不错的功能,例如优先级、重试策略、请求取消。但 RS 提供了更多:更高级的缓存,这是一个很大的缓存管理、请求聚合、更多功能,如重新插入待处理的请求、处理缓存过期而不依赖服务器标头等。
  • RoboSpice 在 UI 线程之外做了更多工作:volley 将在主线程上反序列化您的 POJO,这在我看来是可怕的。使用 RS,您的应用程序将更具响应性。
  • 在速度方面,我们肯定需要指标。 RS现在变得超级快,但我们仍然没有数字可以放在这里。 Volley 理论上应该更快一些,但 RS 现在是大规模并行的……谁知道呢?
  • RoboSpice 提供广泛的扩展兼容性。您可以将它与 okhttp、retrofit、ormlite (beta)、jackson、jackson2、gson、xml 序列化程序、google http 客户端、spring android 一起使用……相当多。 Volley 可以与 ok http 一起使用并使用 gson。就是这样。
  • Volley 提供了比 RS 更多的 UI 糖。 Volley 提供 NetworkImageView,RS 确实提供了一个 spicelist 适配器。就功能而言,目前还没有,但我相信 Volley 在这个主题上更先进。
  • 自 RoboSpice 首次发布以来,已解决了 200 多个错误。它非常健壮,并在生产中大量使用。 Volley 不太成熟,但它的用户群应该会快速增长(谷歌效应)。
  • RoboSpice 在 maven Central 上可用。排球很难找到;)

【讨论】:

  • Robospice 使用 android 服务进行 REST 调用,我们可以使用 Robospice 和 Retrofit 来最小化 gson 解析工作,就像我们可以使用 Volley(基于胎面)和 Robospice 一样? (不知道问的qsn是否正确)我只是在寻找凌空服务!
  • 带服务的排球基本上是RS。或者,按时间顺序,Volley 是没有服务且缺少其他功能的 RS。是的,您可以将 Retrofit 与 RS 一起使用,如果您愿意,甚至可以添加 okhttp。
  • 为什么凌空难找? compile 'com.mcxiaoke.volley:library:1.0.+'
  • @Rob 曾经有一段时间,mcxiaoke 的克隆不可用。您必须在应用中手动包含 volley。
  • "volley 将反序列化主线程上的 POJO"。如果这是一个问题,您可以接收返回的 JSON 数据并在单独的线程上自行反序列化。
【解决方案4】:

AFNetworking for Android:

Fast Android Networkinghere

Fast Android Networking Library 支持所有类型的 HTTP/HTTPS 请求,例如 GET、POST、DELETE、HEAD、PUT、PATCH

Fast Android Networking Library 支持下载任何类型的文件

Fast Android Networking Library 支持上传任何类型的文件(支持分段上传)

Fast Android Networking Library 支持取消请求

Fast Android Networking Library 支持为任何请求设置优先级(LOW、MEDIUM、HIGH、IMMEDIATE)

快速 Android 网络库支持 RxJava

由于它使用 OkHttp 作为网络层,它支持:

Fast Android Networking Library 支持 HTTP/2 支持允许对同一主机的所有请求共享一个套接字

Fast Android Networking Library 使用连接池来减少请求延迟(如果 HTTP/2 不可用)

透明 GZIP 缩小下载大小

Fast Android Networking Library 支持响应缓存,完全避免网络重复请求

谢谢:图书馆是我创建的

【讨论】:

  • 您声明您的库支持 HTTP/2,但您没有说是否有 API 要求支持 HTTP/2。我的理解是,低于 5.0 的 Android API 级别没有正确的 SSL 加密方法来支持 HTTP/2。不敲门,只是想全面评估您提出的解决方案。
  • @AmitShekhar:我只是想知道哪一个最适合在 Android 中调用 API。我正在使用 Android Networking Library,那么哪个更适合实现 Retrofit、Volley 或 Android Networking?
  • @Amit Shekhar 快速 Android 网络对于多部分图像上传的效率如何,尤其是在低互联网场景下?
【解决方案5】:

异步 HTTP 客户端循环与 Volley

我的项目的细节是小型 HTTP REST 请求,每 1-5 分钟一次。

我长期使用异步 HTTP 客户端 (1.4.1)。性能优于使用 vanilla Apache httpClient 或 HTTP URL 连接。无论如何,新版本的库对我不起作用:library inter exception cut chain of callbacks.

阅读所有答案促使我尝试新事物。我选择了 Volley HTTP 库。

使用一段时间后,即使没有测试,我也清楚地看到响应时间下降到 1.5x,2x Volley。

也许 Retrofit 比异步 HTTP 客户端更好?我需要尝试一下。 但我敢肯定 Volley 不适合我。

【讨论】:

  • 关于 Retrofit Vs AsyncHttpClient 的任何分析 ???如果是,请发布@Sergey
  • 我使用 AsyncHttpClient 已经有几年了。不好的部分是 github repo 有 2 年没有提交。
  • 它不再是实际的了,异步 http 太老了。考虑换一个库。排球也成为了非常不错的选择。
  • Sergey,@IshRoid 我仍在寻找您的问题的答复/跨度>
【解决方案6】:

根据我使用 Volley 的经验来补充一点讨论:

  1. Volley 不处理任何意义上的流式上传或下载。也就是说,整个请求正文必须在内存中,您不能使用OutputStream 将请求正文写入底层套接字,也不能像基本HttpURLConnection 那样使用InputStream 读取响应正文.因此,Volley 对于上传或下载大文件来说是一个糟糕的选择。您的请求和响应应该很小。这是我个人遇到的 Volley 的最大限制之一。值得一提的是,OkHttp 确实有处理流的接口。

  2. 官方文档的缺乏很烦人,尽管我已经能够通过阅读源代码来解决这个问题,这很容易理解。更麻烦的是,据我所知,Volley 没有官方发布版本,也没有 Maven 或 Gradle 工件,因此将其作为依赖项进行管理变得比 Square 发布的任何库更令人头疼.您只需克隆一个 repo,构建一个 jar,然后您就可以靠自己了。寻找错误修复?获取并希望它在那里。你也可能得到一些其他的东西;它不会被记录在案。在我看来,这实际上意味着 Volley 是一个不受支持的 3rd 方库,即使代码库相当活跃。警告购买者。

  3. 总的来说,将 Content-Type 绑定到类/请求类型(JsonObjectRequest、ImageRequest 等)有点尴尬,并且会降低调用代码的灵活性,因为您需要绑定Volley 现有的请求类型层次结构。我喜欢直接将 Content-Type 设置为像其他任何标题一样的标题(顺便说一下,不要对 Volley 这样做;您最终会得到两个 Content-Type 标题!)。不过,这只是我的个人意见,可以解决。

这并不是说 Volley 没有一些有用的功能。确实如此。易于定制的重试策略、透明缓存、取消 API 以及对请求调度和并发连接的支持都是很棒的功能。只需知道它并不适用于所有 HTTP 用例(请参阅上面的第 1 项),并且在您的应用中将 Volley 投入生产使用会涉及一些令人头疼的问题(第 2 项)。

【讨论】:

  • 完整的内存加载是我慢慢杀死我的原因。感谢上帝,其他人提到了它。
  • 该库还可能会为您的请求正文制作一份防御性副本,因此大型请求的内存消耗可能是您预期的两倍。
【解决方案7】:

我最近发现了一个名为ion 的库,它为桌面带来了一些额外的东西。

ion 内置支持与 ImageView、JSON(在 GSON 的帮助下)、文件和非常方便的 UI 线程支持集成的图像下载。

我在一个新项目中使用它,到目前为止效果很好。它的使用比 Volley 或 Retrofit 简单得多。

【讨论】:

  • ion vs retrofit,你会推荐哪一个?
  • 改造比离子好
【解决方案8】:

除了已接受的答案和 LOG_TAG 所说的内容之外......为了让 Volley 在后台线程中解析您的数据,您必须将 Request<YourClassName> 子类化,因为在主线程上调用 onResponse 方法并在主线程上解析如果您的响应很大,可能会导致 UI 滞后。 阅读here 了解如何做到这一点。

【讨论】:

  • 对... volley 解析主线程上的响应,当响应非常大时会导致用户滞后。
【解决方案9】:

改造 1.9.0 与 RoboSpice

我在我的应用程序中同时使用这两种方法。

每当我解析嵌套的 JSON 类时,Robospice 的运行速度都比 Retrofit 快。因为 Spice Manger 会为您做一切。在 Retrofit 中你需要创建 GsonConverter 并反序列化它。

我在同一个活动中创建了两个片段,并使用两个相同类型的 URL 同时调用。

09-23 20:12:32.830  16002-16002/com.urbanpro.seeker E/RETROFIT﹕   RestAdapter Init
09-23 20:12:32.833  16002-16002/com.urbanpro.seeker E/RETROFIT﹕ calling the method
09-23 20:12:32.837  16002-16002/com.urbanpro.seeker E/ROBOSPICE﹕ initialzig spice manager
09-23 20:12:32.860  16002-16002/com.urbanpro.seeker E/ROBOSPICE﹕ Executing the method
09-23 20:12:33.537  16002-16002/com.urbanpro.seeker E/ROBOSPICE﹕ on SUcceess
09-23 20:12:33.553  16002-16002/com.urbanpro.seeker E/ROBOSPICE﹕ gettting the all contents
09-23 20:12:33.601  16002-21819/com.urbanpro.seeker E/RETROFIT﹕ deseriazation starts
09-23 20:12:33.603  16002-21819/com.urbanpro.seeker E/RETROFIT﹕ deseriazation ends

【讨论】:

  • RoboSpice 现已过时。
【解决方案10】:

还有另一种选择: https://github.com/apptik/jus

  • 它像 Volley 一样是模块化的,但扩展性更强,文档也在改进,支持开箱即用的不同 HTTP 堆栈和转换器
  • 它有一个生成服务器 API 接口映射的模块,例如 Retrofit
  • 它还支持 JavaRx

还有许多其他方便的功能,如标记、转换器等。

【讨论】: