## (一).前言: 对于网络框架这部分,其实也一直想写点东西总结一下,很长的一段时间对于网络请求这块,在我刚开始做Android开发的时候还是2.2,2.3版本居多,那时候我们的项目中经常使用的是HttpURLConnection和HTTPClient来进行HTTP通信。不过这两种方式的用法有很多复杂的地方,我们在实际使用中都要进行封装,一个HTTP请求自定义封装工具类,方法一多一般就是几百行或者几千行代码,这样如果封装不好就会出现很多重复的代码甚至Bug。慢慢的就出现了很多网络请求框架例如:AsyncHttpClient,OkHttp,google亲儿子Okhttp之类的。现在比较热门的网络请求框架:Volley,Okhttp,这些已经在项目中得到很多的应用。   从我这边的角度来讲,我这边项目网络请求这块的演变如下:HttpURLConnection,HTTPClient->Volley->Okhttp。所以我这边会把Volley和Okhttp这两个框架的使用,进阶,分装都会讲一遍,也方便初学者或者各位能够学会使用以及明白相关的原理。 Volley系列教程大纲如下: 1. Volley完全解析之基础 2. Volley完全解析之进阶 3. Volley完全解析之源码分析        今天我们首先来进入Volley使用基础阶段,会涉及到字符串,JSON,图片等等网络数据请求相关方法的使用。 FastDev4Android框架项目地址:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android) ## (二).Volley基本介绍: 2.1.Volley简介: 2013年Google  I/O大会的时候GoogleAndroid开发团队推出了一个新网络数据请求框架Volley网络通信库,它能够使得通信速度更加快,更加简单以及更健壮。看一下官网的发布图片: ![](https://box.kancloud.cn/2016-01-18_569c8eb843d6d.jpg) 发射火弓箭的图有点类似流星,从这幅图我们可以看出来Volley比较适合数据量不大但是通信频繁的场景。它当初的设计目标就是非常适合去进行数据量不大,但是网络通信比较频繁的操作。但是如果数据量很大的网络例如:文件下载这类的,Volley框架的效率就会比较差了。 2.2.Volley功能特点: 1. 提供字符串,文本,JSON图片等数据的异步下载,同时提供回调接口 2. Request请求的优先级以及排序 3. 网络请求,图片等相关缓存功能 4. 网络请求cancel机制 5. 和原生组件生命周期联动机制(例如:Activity结束的时候,会取消掉网络请求)等 2.3.Volley框架依赖配置: Volley库地址为:https://android.googlesource.com/platform/frameworks/volley你可以使用git进行克隆一份,当然这个地址是被墙掉得。你也可以去github中进行clone下载;  [https://github.com/mcxiaoke/android-volley](https://github.com/mcxiaoke/android-volley) 然后采用library依赖的方式导入项目,或者编译成jar包,在进行引入。当然如果你使用的是AndroidStudioIDE,你可以直接添加以下依赖即可: ~~~ compile'com.mcxiaoke.volley:library:1.0.19' ~~~          在我们今天演示的例子项目中,我这边直接采用库依赖的方式,如果大家如果clone我这边FastDev4Android项目,可以直接看到源代码,便于后面我们对于源代码的修改以及功能封装。 ## (三).Volley使用讲解: OK有了上面的准备工作,我们现在开始正式使用Volley框架进行我们的网络请求,要实现网络数据请求主要要记住下面三步骤: 1.创建RequestQueue对象 2.创建XXRequest对象(XX代表String,JSON,Image等等) 3.把XXRequest对象添加到RequestQueue中即可 3.1.StringRequest使用    我们现在开始使用StringRequest来获取文本字符串数据,首先创建RequestQueue对象: ~~~ RequestQueue requestQueue=Volley.newRequestQueue(this); ~~~ 该通过Volley的静态方法newRequestQueue(Context)来获取一个请求队列对象,内部设计有请求缓存,系统版本区分请求,并且设计适合于高并发。间接着创建StringRequest对象来发起HTTP请求,然后接收相应数据: ~~~ StringRequest stringRequest=new StringRequest(Request.Method.GET, "http://www.sina.com.cn", new Response.Listener<String>() { @Override public void onResponse(String response) { tv_result.setVisibility(View.VISIBLE); img_result.setVisibility(View.GONE); tv_result.setText(response.toString()); } }, new Response.ErrorListener(){ @Override public void onErrorResponse(VolleyError error) { } }); ~~~ 创建StringRequest对象传入四个参数: 1. 请求方法GET/POST/或者其他 2. 请求服务器的目标地址 3. 服务器数据成功响应回调 4. 服务器数据失败响应回调 第三步,就是StringRequest请求对象加入请求队列中(RequestQueue) ~~~ requestQueue.add(jsonObjectRequest); ~~~ 以上就完成了StringRequest的请求操作,运行效果如下图: ![](https://box.kancloud.cn/2016-01-18_569c8eb88c106.jpg) 上面我们就是完成了StringRequest的请求一种实例,不过上面只是简单的Get请求,Volley框架也还是支持Post请求,但是比较遗憾的是Volley框架没有直接提供设置Post请求参数的方法,但是我们实现getParams()方法来添加参数,更加让我们开发使用起来简单的方法就是修改Volley框架源代码,后面使用进阶中我们会将到源代码相关修改。现在我们继续往下看。 3.2.JsonObjectRequest和JsonArrayRequest使用    JsonObjectRequest和JsonArrayRequest都是集成自JsonRequest,而JsonRequest又是Request的子类。所以我们使用起来还是和StringRequest的方式差不多。 ~~~ JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(Request.Method.GET , "http://interface.zttmall.com/update/mallUpdate",null,new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Gson gson=new Gson(); tv_result.setVisibility(View.VISIBLE); img_result.setVisibility(View.GONE); tv_result.setText(gson.fromJson(response.toString(),UpdateBean.class).toString()); } }, new Response.ErrorListener(){ @Override public void onErrorResponse(VolleyError error) { } }); requestQueue.add(jsonObjectRequest); ~~~ 这边例子是请求一个地址,返回的是JSON数据格式的数据,我们这边使用还定义了一个UpdateBean实体类,使用Gson来对数据进行解析,最后把对象打印出来。效果如下: ![](https://box.kancloud.cn/2016-01-18_569c8eb8f06d1.jpg) 查看以上的onResponse(JSONObject object)回调方法,传入参数为JSONObject对象,因为我们的接口返回就是单条的JSON数据,内部已经把JSON数据格式化成JSONObject对象了。得到对象我们直接解析即可。至于JsonArrayRequest的使用和JsonRequest使用差不多,一个单条,一个是多条而已。这边就不演示了。 3.3.ImageRequest使用 学完上面的文本,josn等数据的加载,现在我们来看一下图片的加载模块了,Volley对于图片加载也给我们提供相应的工具类以及相关方法,主要是以下三种: 1. ImageRequest 2. ImageLoder 3. NetWorkImageView 下面我们来分别学习一下这三种图片加载方法,首先讲一下ImageRequest ImageRequest也是继承自Request类,用法步骤和上面的三步骤战略差不多,整体代码如下: ~~~ ImageRequest imageRequest=new ImageRequest("http://interface.zttmall.com/Images/upload/image/20150325/20150325083110_0898.jpg" , newResponse.Listener<Bitmap>() { @Override public void onResponse(Bitmap response) { tv_result.setVisibility(View.GONE); img_result.setVisibility(View.VISIBLE); img_result.setImageBitmap(response); } }, 300, 300,ImageView.ScaleType.FIT_XY, Bitmap.Config.ARGB_8888, newResponse.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }); requestQueue.add(imageRequest); ~~~ 创建ImageRequest对象,然后加入到请求队列中即可,ImageRequest创建的时候需要传入一下参数: * 图片地址 * 图片请求成功回调 * 图片设置宽 * 图片设置高 * 图片拉伸类型 * 图片属性 * 图片请求失败回调 最后ImageRequest对象添加到请求队列中即可。然后加载显示图片如下: ![](https://box.kancloud.cn/2016-01-18_569c8eb9231f9.jpg) 3.4.ImageLoader使用 现在我们来看图片加载第二种方式使用ImageLoader,该类的使用方法就需要改变一下,因为ImageLoader可以把图片缓存结合进去,例如我们集合LruCache工具。所以整体来讲还是比ImageRequest功能强大了一点。使用步骤如下: 1. 创建RequestQueue请求队列对象 2. 创建ImageLoader图片加载器对象 3. 获取ImageListener图片监听器 4. 带哦用ImageLoader.get()方法来进行加载图片 下面我们来具体演示一下使用ImageLoder来加载图片。 首先创建RequestQueue对象: ~~~ RequestQueue requestQueue=Volley.newRequestQueue(this); ~~~ 创建ImageLoader对象,需要创建图片缓存器 ~~~ packagecom.chinaztt.fdv; importandroid.graphics.Bitmap; importcom.android.volley.toolbox.ImageLoader; /** * 当前类注释:图片缓存器,实现ImageLoder.ImageCache实现其中的方法,具体图片怎么样缓存让我们自己来实现 * 这样可以考虑到将来的扩展性 * 项目名:FastDev4Android * 包名:com.chinaztt.fdv * 作者:江清清 on 15/11/12 12:31 * 邮箱:jiangqqlmj@163.com * QQ: 781931404 * 公司:江苏中天科技软件技术有限公司 */ public class Fdv_ImageCache implements ImageLoader.ImageCache { @Override public Bitmap getBitmap(String url) { return null; } @Override public void putBitmap(String url, Bitmapbitmap) { } } ~~~ 这边我创建了一个Fdv_ImagCache类实现ImageLoader.ImageCache接口,并且实现其中的两个方法,这样图片的缓存具体方式让我们用户自己来实现,可以增强系统缓存的可扩展性,自定义搞定。这边我们暂时不具体实现方法直接给了空实现,后面的进阶讲解中会具体来将这些问题。下面为ImageLoader对象创建: ~~~ ImageLoader imageLoader=new ImageLoader(requestQueue, new Fdv_ImageCache()); ~~~ 分别传入请求队列,以及图片缓存器即可。 下边获取ImageListener监听器: ~~~ ImageLoader.ImageListener listener=ImageLoader.getImageListener(img_result,R.drawable.ic_loading,R.drawable.ic_loading); ~~~ 直接通过ImageLoader的静态方法getImageListener()来进行获取,传入三个参数分别为: * 需要实现图片的控件imageview * 正在加载过程中的默认图片ID * 图片下载失败显示的图片ID 最后使用ImageLoader调用get方法来下载并且显示图片 ~~~ imageLoader.get("http://interface.zttmall.com//Images//upload//image//20150328//20150328105404_2392.jpg",listener); ~~~ OK这样就搞定了,让我们来看效果显示: ![](https://box.kancloud.cn/2016-01-18_569c8eb955808.jpg) 3.5.NetworkImageView使用 最后我们来讲一下第三种方式加载图,NetworkImageView,该为自定义的ImageView控件,对ImageView的功能进行了扩展,加入了图片下载的功能,具体使用方法如下: 1. 创建RequestQueue对象 2. 创建Imageloader对象 3. 布局文件使用NetworkImageView自定义控件 4. 使用获取控件调用setImageUrl()方法即可 布局文件如下: ~~~ <com.android.volley.toolbox.NetworkImageView android:id="@+id/img_result_network" android:layout_width="300dp" android:layout_height="300dp" android:layout_centerHorizontal="true"/> ~~~ 间接着创建ImageLoader对象: ~~~ ImageLoader network_imageLoader=new ImageLoader(requestQueue, new Fdv_ImageCache()); ~~~ 然后获取NetworkImageView控件并且调用setimageUrl()方法如下: ~~~ img_result_network.setImageUrl("http://interface.zttmall.com//Images//upload//image//20150325//20150325083214_8280.jpg",network_imageLoader); ~~~         setImageUrl()传入图片地址以及图片加载器imageloader,这样就可以自动下载图片并且进行显示,不过在此之前,我们可以对该控件进行相关设置:setDefaultImageResId(),  setErrorImageResId()分别设置默认加载图片或者图片下载失败显示图片。 具体实例效果如下: ![](https://box.kancloud.cn/2016-01-18_569c8eb9b49ba.jpg) ## (四).结束语: 到此为止我们已经讲完了Volley框架的基本介绍以及相关工具的使用(例如:StringRequest,JsonRequest,JsonArrayRequest,ImageRequest,ImageLoader,NetworkImageView等),具体例如Post请求参数修改,图片缓存器,使用最佳实践等相关高级进阶相关会在下一讲中更新。具体实例和框架注释过的全部代码已经上传到FastDev4Android项目中了。 同时欢迎大家去Github站点进行clone或者下载浏览: [https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android) 同时欢迎大家star和fork整个开源快速开发框架项目~