【FastDev4Android框架开发】Volley完全解析之进阶最佳实践与二次封装(二十七)

jerry Android 2015年11月26日 收藏

().前言:   

        上一讲我们已经对Volley使用基础阶段涉及到字符串,JSON,图片等等网络数据请求相关方法的使用。今天我们对于Volley框架来一个进阶使用扩展封装,以及对上一篇遗留的问题做一下具体修改使用。主要涉及新增GsonRequest,ImageLoader列表图片加载,ImageCache,Volley框架StringRequest二次封装以及post请求新增设置请求参数方法。

        FastDev4Android框架项目地址:https://github.com/jiangqqlmj/FastDev4Android

().post请求扩展请求参数方法

       还记得前面文章我们只是使用RequestGET请求方法,当然作为完善的网络框架POST请求必须支持,不过很可惜的是Volley框架没有给我们显示的提供设置POST请求参数的方法,不过我们有两种方法来进行设置。不过在做之前我们需要先从源码角度来分析一下。

        查看源码,我们发现Volley请求最终会被封装成HttpRequest子类对象HttpUrlRequest,该方法在HttpClientStack中的createHttpRequest()方法,代码和相关注释如下:


  1. /**
  2.      * 进行创建httprequest,这边获取httprequest的子类,httpurlrequest
  3.      * Creates the appropriate subclass ofHttpUriRequest for passed in request.
  4.      */
  5.     @SuppressWarnings("deprecation")
  6.     /* protected */ static HttpUriRequest createHttpRequest(Request<?> request,
  7.             Map<String, String>additionalHeaders) throws AuthFailureError {
  8.         switch (request.getMethod()) {
  9.             case Method.DEPRECATED_GET_OR_POST:{
  10.                 // This is the deprecated waythat needs to be handled for backwards compatibility.
  11.                 // If the request's post bodyis null, then the assumption is that the request is
  12.                 // GET.  Otherwise, it is assumed that the request isa POST.
  13.                 byte[] postBody =request.getPostBody();
  14.                 if (postBody != null) {
  15.                     HttpPost postRequest = new HttpPost(request.getUrl());
  16.                     postRequest.addHeader(HEADER_CONTENT_TYPE,request.getPostBodyContentType());
  17.                     HttpEntity entity;
  18.                     entity = new ByteArrayEntity(postBody);
  19.                    postRequest.setEntity(entity);
  20.                     return postRequest;
  21.                 } else {
  22.                     return newHttpGet(request.getUrl());
  23.                 }
  24.             }
  25.             case Method.GET:
  26.                 return newHttpGet(request.getUrl());
  27.             case Method.DELETE:
  28.                 return newHttpDelete(request.getUrl());
  29.             case Method.POST: {
  30.                 HttpPost postRequest = new HttpPost(request.getUrl());
  31.                postRequest.addHeader(HEADER_CONTENT_TYPE,request.getBodyContentType());
  32.                 //设置请求体 body信息 -如果请求体不为空---[注意]
  33.                setEntityIfNonEmptyBody(postRequest, request);
  34.                 return postRequest;
  35.             }
  36.             case Method.PUT: {
  37.                 HttpPut putRequest = new HttpPut(request.getUrl());
  38.                putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
  39.                setEntityIfNonEmptyBody(putRequest, request);
  40.                 return putRequest;
  41.             }
  42.             case Method.HEAD:
  43.                 return new HttpHead(request.getUrl());
  44.             case Method.OPTIONS:
  45.                 return new HttpOptions(request.getUrl());
  46.             case Method.TRACE:
  47.                 return new HttpTrace(request.getUrl());
  48.             case Method.PATCH: {
  49.                 HttpPatch patchRequest = newHttpPatch(request.getUrl());
  50.                patchRequest.addHeader(HEADER_CONTENT_TYPE,request.getBodyContentType());
  51.                setEntityIfNonEmptyBody(patchRequest, request);
  52.                 return patchRequest;
  53.             }
  54.             default:
  55.                 throw newIllegalStateException("Unknown request method.");
  56.         }
  57.     }


注意查看以上caseMethod.POST部分中的setEntityIfNonEmptyBody();中进行设置请求体相关数据:

  1.  /**
  2.      * 如果request的请求体不为空,进行设置请求体信息
  3.      * @param httpRequest
  4.      * @param request
  5.      * @throws AuthFailureError
  6.      */
  7.     private static void setEntityIfNonEmptyBody(HttpEntityEnclosingRequestBase httpRequest,
  8.             Request<?> request) throws AuthFailureError {
  9.         byte[] body = request.getBody();
  10.         if (body != null) {
  11.             HttpEntity entity = new ByteArrayEntity(body);
  12.             httpRequest.setEntity(entity);
  13.         }
  14.     }

然后会执行RequestgetBody()方法来获取请求体。



  1. /**
  2.      * Returns the raw POST or PUT body to besent.
  3.      * 如果请求是POST或者PUT方法,去获取请求参数信息,然后设置到请求中
  4.      * <p>By default, the body consistsof the request parameters in
  5.      * application/x-www-form-urlencodedformat. When overriding this method, consider overriding
  6.      * {@link #getBodyContentType()} as well tomatch the new body format.
  7.      *
  8.      * @throws AuthFailureError in the event ofauth failure
  9.      */
  10.     public byte[] getBody() throws AuthFailureError {
  11.         //获取请求参数信息
  12.         Map<String, String> params =getParams();
  13.         if (params != null ms.size() > 0) {
  14.             return encodeParameters(params,getParamsEncoding());
  15.         }
  16.         return null;
  17.     }


最后会获取XxxRequest的基类Requst类中的getParams()来获取请求参数信息,然后设置进去。

OK这个设置POST请求参数信息的流程大家应该能清楚吧。但是Volley源代码这边就直接返回null,如下:


  1. protected Map<String, String> getParams() throws AuthFailureError {
  2.         return null;
  3.     }


又因为Volley是开源的,那么下面我们开源对Request和XxxRequest类进行改造修改源代码,往外提供POST请求参数设置的方法,修改步骤如下:

        2.1.Request类一个Map对象mParams,然后添加set方法,然后在getParams()进行returnmParams。具体修改如下:


  1. /**
  2.      * 自定义修改 新增POST请求参数map
  3.      */
  4.     protected Map<String,String> mParams=null;
  5.     public void setParams(Map<String,String> params) {
  6.         this.mParams = params;
  7.     }



  1. /**
  2.      * 进行获取post请求参数数据
  3.      * Returns a Map of parameters to be usedfor a POST or PUT request.  Can throw
  4.      * {@link AuthFailureError} asauthentication may be required to provide these values.
  5.      *
  6.      * <p>Note that you can directlyoverride {@link #getBody()} for custom data.</p>
  7.      *
  8.      * @throws AuthFailureError in the event ofauth failure
  9.      */
  10.     protected Map<String, String> getParams() throws AuthFailureError {
  11.         //return null;
  12.         //重新进行返回params
  13.         return mParams;
  14.     }

       2.2.间接着我们对StringRequest类进行扩展一个构造方法,加入请求参数Map对象,具体代码如下:


  1. /**
  2.      * 扩展POST请求构造函数
  3.      * @param url 请求地址
  4.      * @param listener   数据请求加载成功监听器
  5.      * @param errorListener  数据请求加载失败监听器
  6.      * @param params  POST请求参数
  7.      */
  8.     public StringRequest(String url,Listener<String> listener, ErrorListenererrorListener,Map<String,String> params) {
  9.         this(Method.POST, url, listener,errorListener);
  10.         //进行初始化Request中post 请求参数
  11.         setParams(params);
  12.     }


   OK这两步修改就完成了POST请求参数设置扩展,下面我们来一看一下具体使用方法:


  1. RequestQueue requestQueue=Volley.newRequestQueue(this);
  2.               //修改Volley源代码,扩展StringRequest支持post参数设置
  3.                 Map<String,String>params=new HashMap<String,String>();
  4.                params.put("username","zhangsan");
  5.                params.put("password","12345");
  6.                 StringRequest post_stringRequest=new StringRequest("http://10.18.3.123:8080/SalesWebTest/TestVolleyPost",new Response.Listener<String>() {
  7.                     @Override
  8.                     public void onResponse(String response) {
  9.                        tv_result.setVisibility(View.VISIBLE);
  10.                        img_result.setVisibility(View.GONE);
  11.                        tv_result.setText(response.toString());
  12.                     }
  13.                 }, new Response.ErrorListener(){
  14.                     @Override
  15.                     public void onErrorResponse(VolleyError error) {
  16.  
  17.                     }
  18.                 },params);
  19.                requestQueue.add(post_stringRequest)


       这样就完成POST请求参数设置的扩展,另外的一种方案是创建StringRequest对象的时候实匿名类中重写getParams()方法,然后构造Map对象设置参数信息return该对象即可。不过个人觉的这种方案不推荐还是使用设置的方法比较好。

().ImageloaderImageCache

      在前面使用ImageLoder对象加载图片的时候,有一个优点我们没有深入讲解,因为ImageLoader是支持缓存功能,所以我们在创建ImageLoader需要传入一个缓存管理器,里面传入我们自定义的缓存策略,Fdv_ImageCache我们这边引入LruCache算法具体实现如下:


  1. packagecom.chinaztt.fdv;
  2. importandroid.graphics.Bitmap;
  3. importandroid.util.LruCache;
  4. importcom.android.volley.toolbox.ImageLoader;
  5. /**
  6.  * 当前类注释:图片缓存器,实现ImageLoder.ImageCache实现其中的方法,具体图片怎么样缓存让我们自己来实现
  7.  * 这样可以考虑到将来的扩展性
  8.  * 项目名:FastDev4Android
  9.  * 包名:com.chinaztt.fdv
  10.  * 作者:江清清 on 15/11/12 12:31
  11.  * 邮箱:jiangqqlmj@163.com
  12.  * QQ: 781931404
  13.  * 公司:江苏中天科技软件技术有限公司
  14.  */
  15. public class Fdv_ImageCache  implements ImageLoader.ImageCache {
  16.     private LruCache<String, Bitmap>mCache=null;
  17.     private static final intCACHE_MAX_SIZE = 8 * 1024 * 1024;  //默认缓存大小为8M
  18.     public Fdv_ImageCache(){
  19.         if(mCache==null){
  20.             mCache = new LruCache<String,Bitmap>(CACHE_MAX_SIZE) {
  21.                 @Override
  22.                 protected int sizeOf(Stringkey, Bitmap bitmap) {
  23.                     return bitmap.getRowBytes()* bitmap.getHeight();
  24.                 }
  25.             };
  26.         }
  27.     }
  28.     /**
  29.      * 从缓存中获取图片
  30.      * @param url  获取图片key  当然该key可以根据实际情况 使用url进行变换修改
  31.      * @return
  32.      */
  33.     @Override
  34.     public Bitmap getBitmap(String url) {
  35.         return mCache.get(url);
  36.     }
  37.     /**
  38.      * 向缓存中添加图片
  39.      * @param url  缓存图片key,当然该key可以根据实际情况 使用url进行变换修改 不过规格需要和上面方法的key保持一致
  40.      * @param bitmap  需要缓存的图片
  41.      */
  42.     @Override
  43.     public void putBitmap(String url, Bitmapbitmap) {
  44.        mCache.put(url,bitmap);
  45.     }
  46. }


有了图片缓存机制,然后我们在配合ImageLoader来进行列表上面加载异步图片的实现,具体实现方式如下:


  1. /**
  2.  * 当前类注释:使用ImageLoader来进行测试列表图片异步加载以及缓存
  3.  * 项目名:FastDev4Android
  4.  * 包名:com.chinaztt.fda.test
  5.  * 作者:江清清 on 15/11/12 15:19
  6.  * 邮箱:jiangqqlmj@163.com
  7.  * QQ: 781931404
  8.  * 公司:江苏中天科技软件技术有限公司
  9.  */
  10. @EActivity(R.layout.base_adapter_test_layout)
  11. public class VolleyLoaderActivity  extends BaseActivity {
  12.     @ViewById
  13.     ListView lv_base_adapter;
  14.     @ViewById
  15.     TextView tv_title;
  16.     private QuickAdapter<ModuleBean>mAdapter;
  17.     private List<ModuleBean> moduleBeans;
  18.     private RequestQueue requestQueue;
  19.     private ImageLoader imageLoader;
  20.     private ImageLoader.ImageListener listener;
  21.     @Override
  22.     protected void onCreate(BundlesavedInstanceState) {
  23.         super.onCreate(savedInstanceState);
  24.         requestQueue=Volley.newRequestQueue(this);
  25.         imageLoader=new ImageLoader(requestQueue,new Fdv_ImageCache());
  26.     }
  27.     @AfterViews
  28.     public void setViews(){
  29.        tv_title.setText("Loader 列表图片");
  30.     }
  31.     @AfterViews
  32.     public void bindLvData(){
  33.         moduleBeans=DataUtils.getAdapterData();
  34.         if(mAdapter==null) {
  35.             mAdapter = new QuickAdapter<ModuleBean>(this, R.layout.lv_item_base_layout,moduleBeans){
  36.                 @Override
  37.                 protected void convert(BaseAdapterHelper helper, ModuleBean item) {
  38.                     //列表底下显示进度
  39.                    mAdapter.showIndeterminateProgress(true);
  40.                    helper.setText(R.id.text_lv_item_title, item.getModulename())
  41.                            .setText(R.id.text_lv_item_description, item.getDescription());
  42.                    //setImageUrl(R.id.img_lv_item, item.getImgurl());
  43.                     //使用ImageLoader进行加载图片
  44.                     ImageView loader_img=helper.getView(R.id.img_lv_item);
  45.                    listener=ImageLoader.getImageListener(loader_img,R.drawable.ic_loading,R.drawable.ic_loading);
  46.                    imageLoader.get(item.getImgurl(),listener);
  47.                 }
  48.             };
  49.            lv_base_adapter.setAdapter(mAdapter);
  50.         }
  51.     }
  52. }


运行效果如下:


().GsonRequest封装

          前面我们已经使用过JsonObjectRequest,JsonArrayRequest两个工具类,这边是采用Android自身提供的JSONObject和JSONArray来进行实现解析JSON数据的,不过我们也知道如果我们已经有JSONObject和JSONArray对象然后一步步的解析还是挺麻烦的,所以我们这边可以使用JSON快速解析框架Gson来进行解决这个问题。现在我们自定义一个GsonRequest来专门处理请求GSON解析。在做之前我们先要看一下StringRequest的实现,首先StringRequest是继承Request类然后实现两个抽象方法,间接着提供若干个构造方法(进行数据初始化,请求类型GET/POST…,请求服务器地址,相应成功是否回调接口)。因为StringRequest的实现代码很少而且较简单,那么我们模仿StringRequest类的实现可以写出来一下GsonRequest代码如下:


  1. /**
  2.  * 当前类注释:进行扩展GSON数据解析json数据
  3.  * 项目名:FastDev4Android
  4.  * 包名:com.android.volley.toolbox
  5.  * 作者:江清清 on 15/11/12 18:28
  6.  * 邮箱:jiangqqlmj@163.com
  7.  * QQ: 781931404
  8.  * 公司:江苏中天科技软件技术有限公司
  9.  */
  10. public class GsonRequest<T> extends Request<T> {
  11.     private final Response.Listener<T>listener;
  12.     private Gson gson;
  13.     private Class<T> mClass;
  14.  
  15.     /**
  16.      * GsonRequest 构造函数
  17.      * @param method  请求方法
  18.      * @param url     请求地址
  19.      * @param listener    数据请求成功回调接口
  20.      * @param errorListener  数据请求失败回调接口
  21.      * @param pClass     需要进行解析的类
  22.      */
  23.     public GsonRequest(int method,Stringurl,Response.Listener<T> listener,Response.ErrorListenererrorListener,Class<T> pClass){
  24.          super(method,url,errorListener);
  25.          this.listener=listener;
  26.          gson=new Gson();
  27.          mClass=pClass;
  28.     }
  29.  
  30.     /**
  31.      * GsonRequest 构造函数  默认使用GET请求方法
  32.      * @param url
  33.      * @param listener
  34.      * @param errorListener
  35.      * @param pClass
  36.      */
  37.     public GsonRequest(Stringurl,Response.Listener<T> listener,Response.ErrorListenererrorListener,Class<T> pClass){
  38.         super(Method.GET,url,errorListener);
  39.         this.listener=listener;
  40.         gson=new Gson();
  41.         mClass=pClass;
  42.     }
  43.  
  44.     /**
  45.      * 数据解析
  46.      * @param response Response from thenetwork  网络请求返回数据
  47.      * @return
  48.      */
  49.     @Override
  50.     protected Response<T> parseNetworkResponse(NetworkResponse response) {
  51.         try {
  52.             String jsonStr=new String(response.data,HttpHeaderParser.parseCharset(response.headers));
  53.             Tdata=gson.fromJson(jsonStr,mClass);
  54.             returnResponse.success(data,HttpHeaderParser.parseCacheHeaders(response));
  55.         } catch (UnsupportedEncodingExceptione) {
  56.             return Response.error(newParseError(e));
  57.         }
  58.     }
  59.  
  60.     /**
  61.      * 数据分发
  62.      * @param response The parsed responsereturned by
  63.      */
  64.     @Override
  65.     protected void deliverResponse(T response){
  66.           listener.onResponse(response);
  67.     }
  68. }


          以上实现详解:GsonRequest继承Request,同样提供两个构造函数,然后在parseNetworkResponse()方法中进行解析数据,最后通过Gson组件来封装数据成Bean对象,最终数据回调即可。具体使用方法如下:


  1. GsonRequest<UpdateBean> gsonRequest=new GsonRequest<UpdateBean>("http://interface.zttmall.com/update/mallUpdate",new Response.Listener<UpdateBean>() {
  2.                     @Override
  3.                     public void onResponse(UpdateBean response) {
  4.                        tv_result.setVisibility(View.VISIBLE);
  5.                        img_result.setVisibility(View.GONE);
  6.                        tv_result.setText(response.toString());
  7.                     }
  8.                 }, new Response.ErrorListener(){
  9.                     @Override
  10.                     public void onErrorResponse(VolleyError error) {
  11.  
  12.                     }
  13.                 }, UpdateBean.class);


运行效果如下:


().Volley二次封装(StringRequest为例)

        我们在使用Volley框架请求网络数据获取的时候,一般就是以下三步骤:

           1.创建RequestQueue对象

           2.创建XXRequest对象(XX代表String,JSON,Image等等)

           3.XXRequest对象添加到RequestQueue中即可

        虽然代码量不是不多,不过也还是需要做创建队列对象和请求对象加入到队列中的操作,而创建XxxRequest对象的构造函数中的参数又比较多,所以这边想了一种方案就是在进行网络请求的时候创建和add操作放在内部然后构造函数中的参数减少。所以这边只是以StringRequest为例,简单的封装了一个Get方法请求的方法,其他的功能还有待继续添加更新。

            我们已StringRequest为例二次封装了一个类Fdv_StringRequst,我们来看以下该类的使用方法代码:


  1. newFdv_StringRequest<String>(VolleyTestActivity.this).get("http://www.baidu.com",new Fdv_CallBackListener<String>() {
  2.                     @Override
  3.                     public void onSuccessResponse(String response) {
  4.                     }
  5.                     @Override
  6.                     public void onErrorResponse(VolleyError error) {
  7.  
  8.                     }
  9.                 });


这样即可,不在需要以前的RequestQueuerequestQueue=Volley.newRequestQueue(this);

requestQueue.add(object)这两句代码了,直接在内部已经做了。然后如果Get请求直接调用get()方法即可,不需要显示传入请求方法。下面我们来看一下具体实现:


      5.1.定义Fdv_Volley类,里边是一个单例方法,来获取RequestQueue请求队列对象.


  1. /**
  2.  * 当前类注释:全局Fdv_Volley封装类管理类
  3.  * 项目名:FastDev4Android
  4.  * 包名:com.chinaztt.fdv
  5.  * 作者:江清清 on 15/11/11 23:02
  6.  * 邮箱:jiangqqlmj@163.com
  7.  * QQ: 781931404
  8.  * 公司:江苏中天科技软件技术有限公司
  9.  */
  10. public class Fdv_Volley {
  11.     private static RequestQueue instance;
  12.     public static RequestQueue getInstace(Context pContext){
  13.         if(instance==null){
  14.             instance=Volley.newRequestQueue(pContext);
  15.         }
  16.         return instance;
  17.     }
  18. }


       5.2.定义XxxRequest的基类Fdv_BaseRequest,主要功能获取请求队列对象,然后定义一个addRequest()方法,让子类进行调用,添加当前请求对象到请求队列中。


  1. /**
  2.  * 当前类注释:
  3.  * 项目名:FastDev4Android
  4.  * 包名:com.chinaztt.fdv
  5.  * 作者:江清清 on 15/11/11 22:59
  6.  * 邮箱:jiangqqlmj@163.com
  7.  * QQ: 781931404
  8.  * 公司:江苏中天科技软件技术有限公司
  9.  */
  10. public class Fdv_BaseRequest{
  11.     protected static RequestQueue requestQueue;
  12.     private Context mContext;
  13.     protected Fdv_BaseRequest(ContextpContext){
  14.         this.mContext=pContext;
  15.     }
  16.     /**
  17.      * 请求加入到Volley Request请求队列中
  18.      * @param request
  19.      */
  20.     protected void addRequest(Request request){
  21.        Fdv_Volley.getInstace(mContext).add(request);
  22.     }


      5.3.请求结果回调接口Fdv_CallBackListener,这边暂时只加了两个很简单的方法,后期会进行扩展


  1. /**
  2.  * 当前类注释:
  3.  * 项目名:FastDev4Android
  4.  * 包名:com.chinaztt.fdv
  5.  * 作者:江清清 on 15/11/11 23:18
  6.  * 邮箱:jiangqqlmj@163.com
  7.  * QQ: 781931404
  8.  * 公司:江苏中天科技软件技术有限公司
  9.  */
  10. public interface Fdv_CallBackListener<T> {
  11.     void onSuccessResponse(T response);
  12.     void onErrorResponse(VolleyError error);
  13. }


   5.4.最后是我们的核心类封装过后的StringRequest,Fdv_StringRequest该类继承Fdv_BaseRequest类,在该类中我们暂时只是提供一个get()方法来获取数据中,get()方法的实现还是使用原来的StringRequest进行获取数据,得到数据使用接口回调即可,实现代码如下:


  1. /**
  2.  * 当前类注释:Volley 字符串、文本数据请求封装类
  3.  * 项目名:FastDev4Android
  4.  * 包名:com.chinaztt.fdv
  5.  * 作者:江清清 on 15/11/11 13:43
  6.  * 邮箱:jiangqqlmj@163.com
  7.  * QQ: 781931404
  8.  * 公司:江苏中天科技软件技术有限公司
  9.  */
  10. public class Fdv_StringRequest<T> extends Fdv_BaseRequest{
  11.     public Fdv_StringRequest(Context pContext){
  12.         super(pContext);
  13.     }
  14.     public void get(String url, finalFdv_CallBackListener<T> listener){
  15.         StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
  16.             @Override
  17.             public void onResponse(Stringresponse) {
  18.                 if(listener!=null){
  19.                    listener.onSuccessResponse((T) response);
  20.                 }
  21.             }
  22.         }, new Response.ErrorListener() {
  23.             @Override
  24.             public voidonErrorResponse(VolleyError error) {
  25.                 if(listener!=null){
  26.                    listener.onErrorResponse(error);
  27.                 }
  28.             }
  29.         });
  30.         addRequest(stringRequest);
  31.     }
  32. }


          OK有了以上的几步骤,我们的对于StringRequest的get方法请求简单封装就完成了,有了这样的封装我们的功能实现就会变得代码稍微少了一点,当然我们现在的封装的功能还非常的弱,后面我这边会继续更新封装功能以及重构,让整个工具类变得更加使用。具体更新代码都会FastDev4Android项目中。后期二次封装的Volley框架代码会在Github库中更新,敬请期待~

        以上所有的功能测试代码如下:


  1. @EActivity(R.layout.volley_test_layout)
  2. public class VolleyTestActivity  extends BaseActivity{
  3.     private static final StringTAG=VolleyTestActivity.class.toString();
  4.     @ViewById
  5.     LinearLayout top_bar_linear_back;
  6.     @ViewById
  7.     TextView top_bar_title,tv_result;
  8.     @ViewById
  9.     ImageView img_result;
  10.     @ViewById
  11.     Buttonbtn_string,btn_json,btn_image_request,btn_image_loader,btn_image_network,btn_string_post,btn_loader_list,btn_gson;
  12.     @ViewById
  13.     NetworkImageView img_result_network;
  14.     private RequestQueue requestQueue;
  15.     @Override
  16.     protected void onCreate(BundlesavedInstanceState) {
  17.         super.onCreate(savedInstanceState);
  18.        requestQueue=Volley.newRequestQueue(this);
  19.     }
  20.    @Click({R.id.top_bar_linear_back,R.id.btn_string,R.id.btn_json,R.id.btn_image_request,R.id.btn_image_loader,R.id.btn_image_network,R.id.btn_string_post,R.id.btn_loader_list,R.id.btn_gson})
  21.     public void backLinearClick(View view){
  22.         switch (view.getId()){
  23.             case R.id.top_bar_linear_back:
  24.                 this.finish();
  25.                 break;
  26.             case R.id.btn_string:
  27.                 //获取字符串
  28.                 Log.d(TAG,"点击获取字符串...");
  29.                 new Fdv_StringRequest<String>(VolleyTestActivity.this).get("http://www.baidu.com",new Fdv_CallBackListener<String>() {
  30.                     @Override
  31.                     public void onSuccessResponse(String response) {
  32.                        tv_result.setVisibility(View.VISIBLE);
  33.                        img_result.setVisibility(View.GONE);
  34.                        tv_result.setText(response.toString());
  35.                     }
  36.                     @Override
  37.                     public void onErrorResponse(VolleyError error) {
  38.  
  39.                     }
  40.                 });
  41. //                StringRequest stringRequest=new StringRequest(Request.Method.GET, "http://www.baidu.com",new Response.Listener<String>() {
  42. //                    @Override
  43. //                    public void onResponse(String response) {
  44. //                       tv_result.setVisibility(View.VISIBLE);
  45. //                       img_result.setVisibility(View.GONE);
  46. //                       tv_result.setText(response.toString());
  47. //                    }
  48. //                }, new Response.ErrorListener(){
  49. //                    @Override
  50. //                    public void onErrorResponse(VolleyError error) {
  51. //
  52. //                    }
  53. //                });
  54. //               requestQueue.add(stringRequest);
  55.                 break;
  56.             case R.id.btn_json:
  57.                 //获取json
  58.                 Log.d(TAG,"点击获取json...");
  59.                 JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(Request.Method.GET
  60.                         , "http://interface.zttmall.com/update/mallUpdate",null,new Response.Listener<JSONObject>() {
  61.                     @Override
  62.                     public void onResponse(JSONObject response) {
  63.                         Gson gson=new Gson();
  64.                        tv_result.setVisibility(View.VISIBLE);
  65.                        img_result.setVisibility(View.GONE);
  66.                        tv_result.setText(gson.fromJson(response.toString(),UpdateBean.class).toString());
  67.                     }
  68.                 }, new Response.ErrorListener(){
  69.                     @Override
  70.                     public void onErrorResponse(VolleyError error) {
  71.  
  72.                     }
  73.                 });
  74.                requestQueue.add(jsonObjectRequest);
  75.                 break;
  76.             case R.id.btn_image_request:
  77.                 //获取图片
  78.                //http:\/\/interface.zttmall.com\/Images\/upload\/image\/20150325\/20150325083110_0898.jpg
  79.                 Log.d(TAG,"点击获取图片...");
  80.                 ImageRequest imageRequest=new ImageRequest("http://interface.zttmall.com/Images/upload/image/20150325/20150325083110_0898.jpg"
  81.                         , newResponse.Listener<Bitmap>() {
  82.                     @Override
  83.                     public void onResponse(Bitmap response) {
  84.                        tv_result.setVisibility(View.GONE);
  85.                        img_result.setVisibility(View.VISIBLE);
  86.                        img_result.setImageBitmap(response);
  87.                     }
  88.                 }, 0, 0,ImageView.ScaleType.FIT_XY, Bitmap.Config.ARGB_8888, newResponse.ErrorListener() {
  89.                     @Override
  90.                     public void onErrorResponse(VolleyError error) {
  91.  
  92.                     }
  93.                 });
  94.                 requestQueue.add(imageRequest);
  95.                 break;
  96.             case R.id.btn_image_loader:
  97.                 //使用imageloader进行获取图片
  98.                 ImageLoader imageLoader=new ImageLoader(requestQueue, new Fdv_ImageCache());
  99.                tv_result.setVisibility(View.GONE);
  100.                img_result.setVisibility(View.VISIBLE);
  101.                 ImageLoader.ImageListener listener=ImageLoader.getImageListener(img_result,R.drawable.ic_loading,R.drawable.ic_loading);
  102.                imageLoader.get("http://interface.zttmall.com//Images//upload//image//20150328//20150328105404_2392.jpg",listener);
  103.                 break;
  104.             case R.id.btn_image_network:
  105.                 //采用NetworkImageView imageview控件
  106.                 ImageLoader network_imageLoader=new ImageLoader(requestQueue, new Fdv_ImageCache());
  107.                img_result_network.setVisibility(View.VISIBLE);
  108.                img_result_network.setImageUrl("http://interface.zttmall.com//Images//upload//image//20150325//20150325083214_8280.jpg",network_imageLoader);
  109.                 break;
  110.             case R.id.btn_string_post:
  111.                 //修改Volley源代码,扩展StringRequest支持post参数设置
  112.                 Map<String,String>params=new HashMap<String,String>();
  113.                params.put("username","zhangsan");
  114.                params.put("password","12345");
  115.                 StringRequestpost_stringRequest=new StringRequest("http://10.18.3.123:8080/SalesWebTest/TestVolleyPost",new Response.Listener<String>() {
  116.                     @Override
  117.                     public void onResponse(String response) {
  118.                        tv_result.setVisibility(View.VISIBLE);
  119.                        img_result.setVisibility(View.GONE);
  120.                        tv_result.setText(response.toString());
  121.                     }
  122.                 }, new Response.ErrorListener(){
  123.                     @Override
  124.                     public void onErrorResponse(VolleyError error) {
  125.  
  126.                     }
  127.                 },params);
  128.                requestQueue.add(post_stringRequest);
  129.                 break;
  130.             case R.id.btn_loader_list:
  131.                 //进行使用ImageLoader加载图片列表
  132.                openActivity(VolleyLoaderActivity_.class);
  133.                 break;
  134.             case R.id.btn_gson:
  135.                 //使用扩展工具 GsonRequest进行请求
  136.                 GsonRequest<UpdateBean> gsonRequest=new GsonRequest<UpdateBean>("http://interface.zttmall.com/update/mallUpdate",new Response.Listener<UpdateBean>() {
  137.                     @Override
  138.                     public void onResponse(UpdateBean response) {
  139.                        tv_result.setVisibility(View.VISIBLE);
  140.                        img_result.setVisibility(View.GONE);
  141.                        tv_result.setText(response.toString());
  142.                     }
  143.                 }, new Response.ErrorListener(){
  144.                     @Override
  145.                     public void onErrorResponse(VolleyError error) {
  146.  
  147.                     }
  148.                 }, UpdateBean.class);
  149.                 requestQueue.add(gsonRequest);
  150.                 break;
  151.         }
  152.     }
  153.     @AfterViews
  154.     public void setViews(){
  155.        top_bar_title.setText("Volley网络框架测试实例");
  156.     }
  157. }


整个功能测试功能点如下图:


().结束语:

         到此为止我们已经讲完了Volley框架进阶部分:POST请求参数修改,图片缓存器,使用最佳实践,二次封装等相关高级进阶。具体实例和框架注释过的全部代码已经上传到FastDev4Android项目中了。同时欢迎大家去Github站点进行clone或者下载浏览:

https://github.com/jiangqqlmj/FastDev4Android 同时欢迎大家starfork整个开源快速开发框架项目~

       最后对于Volley框架二次封装的代码库,我这边会继续进行更新,后面会放入单独的Git库中,库地址后面会放出来的,敬请期待~