Android开发——Volley的使用详解0.前言Android系统中主要提供了HttpURLConnection和HttpClient进行网络通信,但是如果不对其进行封装就很容易就会写出重复代码。因此一些Android网络通信框架应运而生,Volley就是其中的佼佼者,Volley不仅可以进行HTTP通信,也可以轻松加载网络上的图片。Volley设计的初衷就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。原因总结如下:(1)Volley的网络请求线程池默认为4。因此只能并发进行4个请求(多了排队),容易被4个较大文件的下载任务阻塞其余请求。(2)Request的parseNetWorkResponse()方法返回byte[]类型,需要把传输到的数据读到内存中。如果文件过大,容易引发OOM。1.Volley的基本使用1.1HTTPGET请求首先在AS中导入Volley的jar包。[java]viewplaincopy在CODE上查看代码片派生到我的代码片RequestQueuemQueue=Volley.newRequestQueue(getApplicationContext());StringRequeststringRequest_get=newStringRequest((){@OverridepublicvoidonResponse(Stringresponse){Log.d(TAG,response);}},newResponse.ErrorListener(){@OverridepublicvoidonErrorResponse(VolleyErrorerror){Log.e(TAG,error.getMessage(),error);}});mQueue.add(stringRequest);StringRequest的构造函数需要传入三个参数,第一个是URL地址,第二/三个参数是服务器响应成功/失败的回调。若成功则将返回的html代码转为String打印出log。1.2HTTPPOST请求[java]viewplaincopy在CODE上查看代码片派生到我的代码片RequestQueuemQueue=Volley.newRequestQueue(getApplicationContext());StringRequeststringRequest=newStringRequest(Method.POST,url,listener,errorListener){@OverrideprotectedMapString,StringgetParams()throwsAuthFailureError{MapString,Stringmap=newHashMapString,String();map.put(params1,value1);map.put(params2,value2);returnmap;}};mQueue.add(stringRequest);当发出POST请求的时候,Volley会尝试调用StringRequest的父类中的getParams()方法来获取POST参数,因此我们需要在StringRequest中重写getParams()方法,设置POST参数即可。1.3JsonRequest和StringRequest一样,JsonRequest也是继承自Request类的,JsonRequest是一个抽象类,有两个子类JsonObjectRequest和JsonArrayRequest,前者用于请求一段JSON数据的,后者用于请求一段JSON数组。下面是使用前者进行一段Json请求的范例代码。[java]viewplaincopy在CODE上查看代码片派生到我的代码片//队列初始化以及request加入队列略JsonObjectRequestjsonObjectRequest=newJsonObjectRequest(url,null,newResponse.ListenerJSONObject(){@OverridepublicvoidonResponse(JSONObjectresponse){Log.d(TAG,response.toString());}},newResponse.ErrorListener(){@OverridepublicvoidonErrorResponse(VolleyErrorerror){Log.e(TAG,error.getMessage(),error);}});1.4ImageRequestVolley支持对图片的加载,因为ImageRequest也是继承自Request类,因此用法也大同小异。下面直接传入图片url,返回数据后内部解析为bitmap,最后设置给ImageView。否则设置默认图片。[java]viewplaincopy在CODE上查看代码片派生到我的代码片ImageRequestimageRequest=newImageRequest(url_image,newResponse.ListenerBitmap(){@OverridepublicvoidonResponse(Bitmapresponse){imageView.setImageBitmap(response);}},0,0,Config.RGB_565,newResponse.ErrorListener(){@OverridepublicvoidonErrorResponse(VolleyErrorerror){imageView.setImageResource(R.drawable.default_image);}});需要注意的是,第三/四个参数用于指定允许图片最大的宽/高,若网络图片的实际宽高大于该设定值,则会对图片进行压缩,指定成0的话就表示不进行压缩。第五个参数用于指定图片的颜色属性,Bitmap.Config下的几个常量都可以在这里使用,其中ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小。不过这种加载图片的方式并不被推荐,因为下面有更好的。1.5ImageLoaderImageLoader基于ImageRequest实现,并且更加智能,多出了帮图片缓存的功能,还可以过滤掉重复的请求链接。但是ImageLoader已经不再继承自Request类。[java]viewplaincopy在CODE上查看代码片派生到我的代码片//mQueue初始化略ImageLoaderimageLoader=newImageLoader(mQueue,newBitmapCache());ImageListenerlistener=ImageLoader.getImageListener(imageView,R.drawable.default_image,R.drawable.failed_image);imageLoader.get(url_image,listener,200,200);//限制最大宽高publicclassBitmapCacheimplementsImageCache{//内部使用LRU实现privateLruCacheString,BitmapmCache;publicBitmapCache(){//缓存图片的大小设置为10MintmaxSize=10*1024*1024;mCache=newLruCacheString,Bitmap(maxSize){@OverrideprotectedintsizeOf(Stringkey,Bitmapbitmap){returnbitmap.getRowBytes()*bitmap.getHeight();}};}@OverridepublicBitmapgetBitmap(Stringurl){returnmCache.get(url);}@OverridepublicvoidputBitmap(Stringurl,Bitmapbitmap){mCache.put(url,bitmap);}}第二行构造一个ImageLoader对象,其中第二个参数是一个ImageCache对象,参数二为自定义的用户缓存的类BitmapCache,该类继承了ImageCache。第三行获取一个ImageListener对象,传入参数比较简单,看名字就知道了。第四行调用ImageLoader的get()方法来加载图片。1.6NetworkImageView这是第三种加载图片的方式,相对来说也是被用的比较多的方式。NetworkImageView继承自ImageView的,在原生的基础之上加入了加载网络图片的功能。用法仍旧是先创建一个RequestQueue对象和一个ImageLoader对象。接下来是在xml中定义我们的NetworkImageView,宽高表示裁剪到此宽高,wrap_content表示不裁剪。[html]viewplaincopy在CODE上查看代码片派生到我的代码片com.android.volley.toolbox.NetworkImageViewandroid:id=@+id/network_image_viewandroid:layout_width=100dpandroid:layout_height=100dp/在Activity中获取到NetworkImageView实例后,就可以调用它的setDefaultImageResId()方法、setErrorImageResId()方法和setImageUrl()方法来分别设置加载时显示的图片,加载失败时显示的图片,以及目标图片的URL地址。[java]viewplaincopy在CODE上查看代码片派生到我的代码片networkImageView.setDefaultImageResId(R.drawable.default_image);networkImageView.setErrorImageResId(R.drawable.failed_image);networkImageView.setImageUrl(url_image,imageLoader);2.自定义Request在网络上传输的数据常用到XML和JSON格式,那么如果想要请求一条XML/JSON格式的数据就需要拓展我们的Volley。2.1XMLRequest[java]viewplaincopy在CODE上查看代码片派生到我的代码片publicclassStringRequestextendsRequestString{privatefinalListenerStringmListener;publicStringRequest(intmethod,Stringurl,ListenerStringlistener,ErrorListenererrorListener){super(method,url,errorListener);mListener=listener;}publicStringRequest(Stringurl,ListenerStringlistener,ErrorListenererrorListener){this(Method.GET,url,listener,errorListener);}@OverrideprotectedvoiddeliverResponse(Stringresponse){mListener.onResponse(response);}@OverrideprotectedResponseStringparseNetw