Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Volley介绍

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called An Introduction to Volley.
Creating a Weather Application for Mars Using Volley

Chinese (Simplified) (中文(简体)) translation by piaoyixue (you can also view the original English article)

Volley是由Google开发的网络请求库,该库在2013年Google I / O大会上推出的。 由于在Android SDK中缺少在不干扰用户体验的情况下进行网络请求的库,因此开发了Volley库。

在发布Volley库之前,Android程序员如果想在客户端和后台之间开发RESTFul系统,只能使用类  java.net.HttpURLConnection 和类Apache  org.apache.http.client

就算不考虑使用这两个类时出现的错误,除了简单的HTTP事务之外,所有事情都必须从头开始。  如果想缓存图像或优先处理某个请求,则那么这些都必须从头开始。

幸运的是,现在有了Volley库,专门为这些需求而量身打造。

1.为什么使用Volley?

避免使用  HttpUrlConnection 和HttpClient

在较低版本的API(主要是Gingerbread和Froyo)中,  HttpUrlConnectionHttpClient远未完美。 有一些已知错误和bug从未修复过。 此外,  在最后一次API更新(API 22)中HttpClient被弃用,这意味着它将不再被维护,并且在将来的版本中可能被删除。

这些理由足够你决定切换到更可靠的处理网络请求的方式来。

也要避免  AsyncTask

自从引入Honeycomb(API 11)系统以来,网络操作必须在与主线程不同的单独线程上执行。 这一重大变化导致了大量使用 AsyncTask<Params, Progress, Result> 规范。

要使用AsyncTask,首先定义一些准备动作,如在onPreExecute中定义上下文。 然后使用doInBackground 方法执行异步任务。 最后,在onPostExecute中处理结果。 这是非常简单的,比实现服务更容易,并附带了大量的示例和文档。

然而,主要的问题是串行化调用。 使用AsyncTask类,您无法确定首先进行哪个请求,哪一个必须等待。 一切都是先进先出。

例如,当您必须加载附加缩略图列表时,问题就出现了。 当用户向下滚动并预期新的结果时,您不能告诉您的activity,首先加载下一页的JSON,然后再加载上一个页的图像。 这可能会在诸如Facebook或Twitter的应用程序中成为严重的用户体验问题,因为这类APP的新item列表比与其关联的缩略图更重要。

Volley旨在通过引入强大的取消API来解决这个问题。 执行调用时不再需要在onPostExecute中检查activity是否被销毁。 这有助于避免不必要的 NullPointerException异常。

它更快了

前段时间,Google+小组对Android上可用于进行网络请求的各种不同方法进行了一系列的性能测试。 当在RESTful应用程序中使用时,Volley的得分比其他库的分数高出十倍。

它缓存一切

Volley自动缓存请求,这是真正的“拯救生命”。 让我们回到前面给出的例子。 您有一个item列表 - 一个JSON数组,而且每个item都有一个描述和与之关联的缩略图。 现在想想如果用户旋转屏幕会发生什么:activity被摧毁,列表被再次加载,图像也是被再次加载。 这将导致资源浪费和糟糕的用户体验。

Volley被证明能解决这个问题。 它记住以前的调用,并处理activity的销毁和重建。 它缓存所有的东西,而你不必担心它。

小元数据操作

Volley非常适合小调用,例如JSON对象,列表部分,所选item的详细信息等。 它为RESTful应用程序设计,因此能给出了最好的结果。

然而,当用于流式操作和大量下载时,Volley表现不佳。 与一般思维相反,Volley的名字不是来自运动词典。 这是作为重复突发的调用,并且分组在一起的。 这就是为什么这个库不适合这种场合。

2.Under the Hood

Volley在三个不同层次上工作,每个层次    都在自己的线程上运行。

Volley under the hood

主线程

在主线程上,与AsyncTask 规范一致,  只允许触发请求并处理其响应。 没有更多了,也没有更少了。

主要的后果是您可以忽略doInBackground 方法中发生的一切  。 Volley自动管理您以前需要关心的HTTP事务和捕获的网络错误。

缓存和网络线程

当你向队列添加一个请求时,会发生几件事情。 首先,Volley检查请求是否可以从缓存获取服务。 如果可以,缓存的响应被读取、解析和传递。 否则请求被传递给网络线程。

在网络线程上,一系列线程的循环不断工作。 第一个可用的网络线程对请求进行排队、进行HTTP请求、解析响应、写入缓存。 最后,它将解析的响应重新发送回您的主线程,在主线程中的监听器正在等待处理结果。

3. 入门

步骤1:导入Volley

Volley设置并不方便。 看起来好像没有官方的Maven库可用,这是非常令人困惑的。 你必须依靠官方的源代码。 您可以通过多种方式之一导入Volley。

首先,从其存储库下载Volley源代码。 如果你有信心这样做,这个Git  命令可以为你做所有的工作:

直到几个星期前,您可以使用ant命令行(android update project -p .  然后  ant jar)将所有内容包装起来,并使用简单的compile files('libs/volley.jar')在Android Studio项目中导入JAR库  。

最近,Google已将Volley更新为Android Studio构建样式,从而难以创建独立的JAR包。 您仍然可以这样做,但只能使用旧版本的库。 我个人不鼓励你使用这个选项,尽管看起来最快。

您应该以经典的方式设置Volley ,即通过将源代码导入为module。 在Android Studio中,打开项目后,选择“ 文件”>“新建模块”,然后选择“ 导入现有项目”。 选择刚刚下载源代码的目录并确认。 名为Volley的文件夹将显示在您的项目结构中。 Android Studio自动更新您的  settings.gradle文件以包含Volley模块,因此您只需要将compile project(':volley')添加到依赖关系即可完成。

有第三种方式。 您可以添加build.gradle文件的依赖关系部分:

它是官方Google存储库的镜像副本,经常同步和更新。 这可能是最简单和最快速的入门方式了。 但是,请注意,这是一个非官方的 Maven存储库,不能保证,也不由Google支持。

在我看来,投入更多的时间导入官方源代码还是比较好。 这样,您可以轻松地跳转到原来的定义和实现,以便在有疑问的情况下,您可以随时依靠官方的Volley源代码,甚至可以根据需要进行更改。

步骤2:使用Volley

Volley大多数情况下只用两个类工作,  RequestQueueRequest。 您首先创建一个  RequestQueue,它管理工作线程并将解析的结果传递回主线程。 然后,给RequestQueue传递一个或多个  Request 对象。

Request构造函数总是把方法类型(GET,POST等)、资源的URL和事件侦听器作为参数。 然后,根据请求的类型,它可能会要求一些更多的变量。

在下面的例子中,我通过调用一个Volley方法 Volley.newRequestQueue来创建一个RequestQueue对象。 这将使用Volley定义的默认值设置RequestQueue对象。

正如你所看到的,这是非常简单的。 您创建请求并将其添加到请求队列。 你完成了。

请注意,监听器的语法类似于AsyncTask.onPostExecute,只是它变成了onResponse。 这不是巧合。 使用Volley的开发人员有意使库的API与AsyncTask 方法类似 。 这使得从使用AsyncTask切换到Volley更容易。

如果您必须在多个activity中进行多个请求,则应避免使用上述方法Volley.newRequestQueue.add。 最好是实例化一个共享的请求队列,并在您的项目中使用它:

我们将在本系列的下一个教程中专门开发这样的东西。

4.  胜利在望

处理标准要求

Volley可以实现三种非常常见的请求类型:

  • StringRequest
  • ImageRequest
  • JsonRequest

这些类中的每一个都继承了我们之前使用的Result类。 我们已经在前面的例子看过StringRequest了。 让我们来看看JsonRequest工作原理。

美丽。 不是吗? 您可以看到,结果类型已设置为JSONObject。 你也可以请求一个JSONArray如果你想要,使用JsonArrayRequest而不是一个JsonObjectRequest进请求。

如前所述,构造函数的第一个参数是要使用的HTTP方法。 然后,您可以提供从中获取JSON的URL。 上面的例子中的第三个变量是  null。 这很好,因为它表示没有参数将随请求一起发出。 最后,您有监听器接收JSON响应和错误响应。 如果你想忽略错误,你可以传入null  。

获取图像需要做更多的工作。 有三种请求图像的方法。  ImageRequest 是标准的。 它显示在共同的ImageView中请求的图片,该图片通过提供的URL进行获取。 您可能希望Volley执行的所有解码和调整大小操作都发生在工作线程上。 第二个选项是  ImageLoader 类,您可以将其视为大量的编排者ImageRequests,例如加载ListView 图像。 第三个选项是  NetworkImageView,这是ImageView 布局项的一种XML替代。

我们来看一个例子。

第一个参数是图片的URL,第二个参数是监听结果的监听器。 第三和第四个参数是整数maxWidth和  maxHeight。 您可以将它们设置0来忽略这些参数。 之后,ImageRequest 请求ScaleType用于计算所需的图像大小和格式来解码位图。 我建议解码格式总是使用Bitmap.Config.ARGB_8888。 最后,我们传递监听错误的监听器。

请注意,Volley会自动将此请求的优先级设置为LOW

发送POST请求

从GET请求切换到POST请求很简单。 您需要更改Request.Method 请求的构造函数并重写getParams方法,返回包含请求参数的Map<String, String> 。

取消请求

如果要取消所有请求,请将以下代码段添加到  onStop 方法中:

这样,您就不用担心用户在onResponse被调用时activity已经被销毁了的可能性。 因为在这种情况下会抛出NullPointerException异常。 

然而,POST和PUT请求应该继续,即使在用户更改activity之后。 我们可以通过使用标签来实现。 构建GET请求时,向其添加一个标签。

要取消所有待处理的GET请求,我们只需添加以下代码行:

这样,您只能取消GET请求,使其他请求保持不变。 请注意,您现在必须手动处理activity过早销毁的情况。

管理Cookie和请求优先级

Volley不提供设置请求的Cookie的方法,也不提供设置优先级。 这可能在将来研究,因为它是一个严重的遗漏。 但是,暂时还要继承Request类。

对于管理cookies,您可以使用请求的标题来重写getHeaders 方法:

实现后,您可以使用setCookies直接提供请求的Cookie列表。

对于优先级,您还需要继承Request类,重写getPriority 方法。 实现如下:

然后,在主线程上,调用这一行代码来设置请求的优先级:

您可以选择以下四个可能的优先级状态之一:

结论

在本文中,我们研究了Volley网络库的工作原理。 我们首先看到了为什么使用Volley,何时使用Volley而不是已经包含在Android SDK中的另一个解决方案。 然后,我们深入了解该库的细节,查看其工作流程及其支持的请求类型。 最后,我们通过创建简单的请求并实现自定义的请求来处理cookie和优先级,从而达到我们的目的。

在本系列关于Volley的下一部分中,我们将创建一个利用Volley的简单应用程序。 我将展示如何制作火星天气应用程序,使用好奇流动站在火星上收集的天气数据。

关注我们的公众号
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.