android 网络通信框架volly

简介: 1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,今年的Google I/O 2013上,Volley发布了。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。 这是Volley名

1. 什么是Volley

在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,今年的Google I/O 2013上,Volley发布了。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。
这是Volley名称的由来: a burst or emission of many things or a large amount at once
在Google IO的演讲上,其配图是一幅发射火弓箭的图,有点类似流星。见下图

其实,从这幅图,我们也可以看出来,Volley特别适合数据量不大但是通信频繁的场景。

1.1. Volley引入的背景
在以前,我们可能面临如下很多麻烦的问题。

比如以前从网上下载图片的步骤可能是这样的流程:

  • 在ListAdapter#getView()里开始图像的读取。
  • 通过AsyncTask等机制使用HttpURLConnection从服务器去的图片资源
  • 在AsyncTask#onPostExecute()里设置相应ImageView的属性。

而在Volley下,只需要一个函数即可,详细见后面的例子。

再比如,屏幕旋转的时候,有时候会导致再次从网络取得数据。为了避免这种不必要的网络访问,我们可能需要自己写很多针对各种情况的处理,比如cache什么的。

再有,比如ListView的时候,我们滚动过快,可能导致有些网络请求返回的时候,早已经滚过了当时的位置,根本没必要显示在list里了,虽然我们可以通过ViewHolder来保持url等来实现防止两次取得,但是那些已经没有必须要的数据,还是会浪费系统的各种资源。

1.2. Volley提供的功能
简单来说,它提供了如下的便利功能:

  • JSON,图像等的异步下载;
  • 网络请求的排序(scheduling)
  • 网络请求的优先级处理
  • 缓存
  • 多级别取消请求
  • 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)

2. 使用前的准备

引入Volley非常简单,首先,从git库先克隆一个下来:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. git clone https://android.googlesource.com/platform/frameworks/volley  

然后编译为jar包,再在自己的工程里import进来。

注意,这个库要求最低SDK版本为Froyo,即至少要设置android:minSdkVersion为8以上。

3.使用例子
下面简单看看如何使用Volley

3.1. 最简单的get请求
这个例子很简单,从网络取得JSON对象,然后打印出来。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mQueue = Volley.newRequestQueue(getApplicationContext());  
  2. mQueue.add(new JsonObjectRequest(Method.GET, url, null,  
  3.             new Listener() {  
  4.                 @Override  
  5.                 public void onResponse(JSONObject response) {  
  6.                     Log.d(TAG, "response : " + response.toString());  
  7.                 }  
  8.             }, null));  
  9. mQueue.start();  

3.2. 给ImageView设置图片源

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // imageView是一个ImageView实例  
  2. // ImageLoader.getImageListener的第二个参数是默认的图片resource id  
  3. // 第三个参数是请求失败时候的资源id,可以指定为0  
  4. ImageListener listener = ImageLoader.getImageListener(imageView, android.R.drawable.ic_menu_rotate, android.R.drawable.ic_delete);  
  5. mImageLoader.get(url, listener);  

ImageLoader的方法都需要从主线程里来调用。

3.3. 使用NetworkImageView

Volley提供了一个新的控件NetworkImageView来代替传统的ImageView,这个控件的图片属性可以通过

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mImageView.setImageUrl(url, imageLoader)  

来设定。而且,这个控件在被从父控件detach的时候,会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题。
示例代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());  
  2. ... ...  
  3.    
  4. if(holder.imageRequest != null) {  
  5.     holder.imageRequest.cancel();  
  6. }  
  7. holder.imageRequest = mImageLoader.get(BASE_UR + item.image_url, holder.imageView, R.drawable.loading, R.drawable.error);  

注意,这里使用的不是ImageView控件,而是Volley新提供的com.android.volley.NetworkImageView。

另外,注意这里:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());  

ImageLoader构造函数的第二个参数是一个ImageCache的实例(严格来说,是实现ImageCache接口的某具体类的实例)
ImageCache的定义如下(在ImageLoader.java里):

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * Simple cache adapter interface. If provided to the ImageLoader, it 
  3.  * will be used as an L1 cache before dispatch to Volley. Implementations 
  4.  * must not block. Implementation with an LruCache is recommended. 
  5.  */  
  6. public interface ImageCache {  
  7.     public Bitmap getBitmap(String url);  
  8.     public void putBitmap(String url, Bitmap bitmap);  
  9. }  

下面的网址一个lru的cache实现例子,请参考:

https://github.com/suwa-yuki/VolleySample/blob/master/src/jp/classmethod/android/sample/volley/BitmapCache.java

3.5. 使用自己定制的request

我们也可以通过继承Request根据自己的需求来定制自己的request

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. protected Response parseNetworkResponse(NetworkResponse response) {  
  3.     try {  
  4.         String json = new String(  
  5.                 response.data, HttpHeaderParser.parseCharset(response.headers));  
  6.         return Response.success(  
  7.                 gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));  
  8.     } catch (UnsupportedEncodingException e) {  
  9.         return Response.error(new ParseError(e));  
  10.     } catch (JsonSyntaxException e) {  
  11.         return Response.error(new ParseError(e));  
  12.     }  
  13. }  

这段代码节选自: https://gist.github.com/ficusk/5474673

里面使用的gson(com.google.gson.Gson)是JSON的序列化和反序列化的库,可以在JSON和java model object之间进行转换。

以下是使用自定制request的例子:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mRequestQueue.add( new GsonRequest(url, ListResponse.classnull,  
  2.     new Listener() {  
  3.         public void onResponse(ListResponse response) {  
  4.             appendItemsToList(response.item);  
  5.             notifyDataSetChanged();  
  6.         }  
  7.     }  
  8. }  

4. Volley的架构设计

Volley使用了线程池来作为基础结构,主要分为主线程,cache线程和network线程。
主线程和cache线程都只有一个,而NetworkDispatcher线程可以有多个,这样能解决比并行问题。如下图:


如果在一个Activity里面启动了网络请求,而在这个网络请求还没返回结果的时候,如果Activity被结束了,则我们需要写如下代码作为防守:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override public void onPostExecute(Result r) {  
  2.     if (getActivity() == null) {  
  3.         return;  
  4.     }  
  5.     // ...  
  6. }  

Activity被终止之后,如果继续使用其中的Context等,除了无辜的浪费CPU,电池,网络等资源,有可能还会导致程序crash,所以,我们需要处理这种一场情况。

使用Volley的话,我们可以在Activity停止的时候,同时取消所有或部分未完成的网络请求。

Volley里所有的请求结果会返回给主进程,如果在主进程里取消了某些请求,则这些请求将不会被返回给主线程。
比如,可以针对某些个request做取消操作:


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public void onStop() {  
  3.     for (Request <?> req : mInFlightRequests) {  
  4.         req.cancel();  
  5.     }  
  6.     ...  
  7. }  

或者,取消这个队列里的所有请求:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override pubic void onStop() {  
  2.     mRequestQueue.cancelAll(this);  
  3.     ...  
  4. }  

也可以根据RequestFilter或者Tag来终止某些请求:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override public void onStop() {  
  2.     mRequestQueue.cancelAll( new RequestFilter() {})  
  3.     ...  
  4.     // or  
  5.     mRequestQueue.cancelAll(new Object());  
  6.     ...  

5.总结

从演讲的例子来看,Volley应该是简化了网络通信的一些开发,特别是针对如下两种情况:

  • JSON对象
  • 图片加载

但是这个东西也有不实用的地方,比如大数据(large payloads ),流媒体,这些case,还需要使用原始的方法,比如Download Manager等。
总之,如果你要编写网络程序,是不是可以考虑开始使用Volley呢?

Google IO2013网络框架Volley 演讲PDF下载http://download.csdn.net/detail/t12x3456/5686041

目录
相关文章
|
1月前
|
数据库 Android开发 开发者
构建高效Android应用:采用Kotlin协程优化网络请求处理
【2月更文挑战第30天】 在移动应用开发领域,网络请求的处理是影响用户体验的关键环节。针对Android平台,利用Kotlin协程能够极大提升异步任务处理的效率和简洁性。本文将探讨如何通过Kotlin协程优化Android应用中的网络请求处理流程,包括协程的基本概念、网络请求的异步执行以及错误处理等方面,旨在帮助开发者构建更加流畅和响应迅速的Android应用。
|
3月前
|
安全 API Android开发
Android网络和数据交互: 解释Retrofit库的作用。
Android网络和数据交互: 解释Retrofit库的作用。
38 0
|
3月前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
22 0
|
4月前
|
XML Java Android开发
Android App开发网络通信中使用okhttp下载和上传图片、文件讲解及实战(超详细实现用户注册信息上传 附源码)
Android App开发网络通信中使用okhttp下载和上传图片、文件讲解及实战(超详细实现用户注册信息上传 附源码)
138 0
|
8天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
9 0
|
8天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
8 0
|
4月前
|
XML JSON Java
Android App网络通信中通过okhttp调用HTTP接口讲解及实战(包括GET、表单格式POST、JSON格式POST 附源码)
Android App网络通信中通过okhttp调用HTTP接口讲解及实战(包括GET、表单格式POST、JSON格式POST 附源码)
163 0
|
3月前
|
JSON Java Android开发
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
24 0
|
4月前
|
XML JSON Android开发
[Android]网络框架之Retrofit(kotlin)
[Android]网络框架之Retrofit(kotlin)
55 0