zoukankan      html  css  js  c++  java
  • Android 开源框架 ( 六 ) Volley --- Google的轻量级网络通信框架

    一.Volley介绍   

      2013年Google I/O大会上推出的一个新的Android网络通信框架,目标是将HTTP的通信操作再进行简单化,除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。不过谷歌已经停止更新Volley了,现在OkHttp成为新一代网络通信的新宠。

    二.Volley使用

    1.导入jar包

    如果只是用于学习,可以通过gradle引用 compile 'com.mcxiaoke.volley:library:1.0.19' 了解下.但是如果用于项目中,最好下载Google官方的jar包.

    compile 'com.mcxiaoke.volley:library:1.0.19'  

    2.授权

    <uses-permission android:name="android.permission.INTERNET" />

    3.使用JsonObjectRequest get请求方式示例

            //1.创建一个请求队列RequestQueue     
            RequestQueue queue= Volley.newRequestQueue(this);
            //2.创建StringRequest对象 
            JsonObjectRequest request=new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject jsonObject) {
                    //接收返回数据
                    Log.e("success",jsonObject.toString());
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
    
                }
            });
            //3.将请求对象添加到请求队列中
            queue.add(request);

      同样还有一些其他请求:ClearCacheRequest,ImageRequest,JsonArrayRequest,JsonRequest,StringRequest 用法一样.

            


          1.ClearCacheRequest :A synthetic request used for clearing the cache. 用于清除缓存请求类
          2.ImageRequest :A canned request for getting an image at a given URL and calling back with a decoded Bitmap. 通过Url获取对应解码位图decoded BitMap 请求类
          3.JsonArrayRequest :A request for retrieving a {@link JSONArray} response body at a given URL. 通过Url返回一个{@ Link JSONArray}Json数组请求类
          4.JsonObjectRequest :A request for retrieving a {@link JSONObject} response body at a given URL, allowing for an optional {@link JSONObject} to be passed in as part of the request body. 可以通过Url返回一个{@link JSONObject},也可以使用{@link JSONObject}当做请求Request的传递参数.
          5.JsonRequest :A request for retrieving a T type response body at a given URL that also optionally sends along a JSON body in the request specified. 通过Url返回一个定义的泛型T ,也可以使用JSON当做请求Request的传递参数的类
          6.StringRequest :A canned request for retrieving the response body at a given URL as a String. 通过Url返回一个String字符串请求类



      4.使用JsonObjectRequest post请求方式示例

      Post请求,只需要在Request请求里,添加一个参数Request.Method.POST : new JsonObjectRequest(Request.Method.POST,url, new Response.Listener<JSONObject>() {...});其他部分一样.

    RequestQueue queue= Volley.newRequestQueue(this);
            JsonObjectRequest request=new JsonObjectRequest(Request.Method.POST,url, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject jsonObject) {
                    //接收返回数据
                    Log.e("success",jsonObject.toString());
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
    
                }
            });
            queue.add(request);

      通过Request.Method.能看到Volley支持的一些请求方式:
              

      5.HurlStack 与 HttpClientStack 介绍

       Volley是官方出的,volley在设计的时候是将具体的请求客户端做了下封装,也就是说可以支持HttpUrlConnection, HttpClient.当然也可以自己封装支持OkHttp.

      Volley.java类

      

      if (stack == null) {
                if (Build.VERSION.SDK_INT >= 9) {
                    //HttpURLConnection 请求方式
                    stack = new HurlStack();
                } else {
                    // Prior to Gingerbread, HttpUrlConnection was unreliable.
                    // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                    //HttpClient 请求方式
                    stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
                }
            }

    然后具体看下 HurlStack.java 里的HttpUrlConnection请求封装.

      /**
         * An {@link HttpStack} based on {@link HttpURLConnection}.
         */
    public class HurlStack implements HttpStack {
    
        private static final String HEADER_CONTENT_TYPE = "Content-Type";
        
        /**
         * Create an {@link HttpURLConnection} for the specified {@code url}.
         */
        protected HttpURLConnection createConnection(URL url) throws IOException {
            return (HttpURLConnection) url.openConnection();
        }
    
        /**
         * Opens an {@link HttpURLConnection} with parameters.
         * @param url
         * @return an open connection
         * @throws IOException
         */
        private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException {
            HttpURLConnection connection = createConnection(url);
    
            int timeoutMs = request.getTimeoutMs();
            connection.setConnectTimeout(timeoutMs);
            connection.setReadTimeout(timeoutMs);
            connection.setUseCaches(false);
            connection.setDoInput(true);
    
            // use caller-provided custom SslSocketFactory, if any, for HTTPS
            if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
                ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
            }
    
            return connection;
        }
    
        @SuppressWarnings("deprecation")
        /* package */ static void setConnectionParametersForRequest(HttpURLConnection connection,
                Request<?> request) throws IOException, AuthFailureError {
            switch (request.getMethod()) {
                case Method.DEPRECATED_GET_OR_POST:
                    // This is the deprecated way that needs to be handled for backwards compatibility.
                    // If the request's post body is null, then the assumption is that the request is
                    // GET.  Otherwise, it is assumed that the request is a POST.
                    byte[] postBody = request.getPostBody();
                    if (postBody != null) {
                        // Prepare output. There is no need to set Content-Length explicitly,
                        // since this is handled by HttpURLConnection using the size of the prepared
                        // output stream.
                        connection.setDoOutput(true);
                        connection.setRequestMethod("POST");
                        connection.addRequestProperty(HEADER_CONTENT_TYPE,
                                request.getPostBodyContentType());
                        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                        out.write(postBody);
                        out.close();
                    }
                    break;
                case Method.GET:
                    // Not necessary to set the request method because connection defaults to GET but
                    // being explicit here.
                    connection.setRequestMethod("GET");
                    break;
                case Method.DELETE:
                    connection.setRequestMethod("DELETE");
                    break;
                case Method.POST:
                    connection.setRequestMethod("POST");
                    addBodyIfExists(connection, request);
                    break;
                case Method.PUT:
                    connection.setRequestMethod("PUT");
                    addBodyIfExists(connection, request);
                    break;
                case Method.HEAD:
                    connection.setRequestMethod("HEAD");
                    break;
                case Method.OPTIONS:
                    connection.setRequestMethod("OPTIONS");
                    break;
                case Method.TRACE:
                    connection.setRequestMethod("TRACE");
                    break;
                case Method.PATCH:
                    connection.setRequestMethod("PATCH");
                    addBodyIfExists(connection, request);
                    break;
                default:
                    throw new IllegalStateException("Unknown method type.");
            }
        }
    
            private static void addBodyIfExists(HttpURLConnection connection, Request<?> request)
                throws IOException, AuthFailureError {
                byte[] body = request.getBody();
                if (body != null) {
                    connection.setDoOutput(true);
                    connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType());
                    DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                    out.write(body);
                    out.close();
                }
            }
    
    }    

    在看看HttpClientStack.java 里的HttpClient的封装.  注意下哈,HttpClient 已经在Android 6.0 删除.

    /**
     * An HttpStack that performs request over an {@link HttpClient}.
     */
    public class HttpClientStack implements HttpStack {
        protected final HttpClient mClient;
    
        private final static String HEADER_CONTENT_TYPE = "Content-Type";
        
        
        /**
         * Creates the appropriate subclass of HttpUriRequest for passed in request.
         */
        @SuppressWarnings("deprecation")
        /* protected */ static HttpUriRequest createHttpRequest(Request<?> request,
                Map<String, String> additionalHeaders) throws AuthFailureError {
            switch (request.getMethod()) {
                case Method.DEPRECATED_GET_OR_POST: {
                    // This is the deprecated way that needs to be handled for backwards compatibility.
                    // If the request's post body is null, then the assumption is that the request is
                    // GET.  Otherwise, it is assumed that the request is a POST.
                    byte[] postBody = request.getPostBody();
                    if (postBody != null) {
                        HttpPost postRequest = new HttpPost(request.getUrl());
                        postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType());
                        HttpEntity entity;
                        entity = new ByteArrayEntity(postBody);
                        postRequest.setEntity(entity);
                        return postRequest;
                    } else {
                        return new HttpGet(request.getUrl());
                    }
                }
                case Method.GET:
                    return new HttpGet(request.getUrl());
                case Method.DELETE:
                    return new HttpDelete(request.getUrl());
                case Method.POST: {
                    HttpPost postRequest = new HttpPost(request.getUrl());
                    postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
                    setEntityIfNonEmptyBody(postRequest, request);
                    return postRequest;
                }
                case Method.PUT: {
                    HttpPut putRequest = new HttpPut(request.getUrl());
                    putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
                    setEntityIfNonEmptyBody(putRequest, request);
                    return putRequest;
                }
                case Method.HEAD:
                    return new HttpHead(request.getUrl());
                case Method.OPTIONS:
                    return new HttpOptions(request.getUrl());
                case Method.TRACE:
                    return new HttpTrace(request.getUrl());
                case Method.PATCH: {
                    HttpPatch patchRequest = new HttpPatch(request.getUrl());
                    patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
                    setEntityIfNonEmptyBody(patchRequest, request);
                    return patchRequest;
                }
                default:
                    throw new IllegalStateException("Unknown request method.");
            }
        }
        
    }
  • 相关阅读:
    cocos2d-x 配置教程
    cocos2d-x 学习笔记之 CCMenuItemToggle用法
    cocos2d-android-1学习之旅01
    博客园的代码高亮
    JAVA POI 应用系列(2)--读取Excel
    JAVA POI 应用系列(1)--生成Excel
    spring和hibernate的整合
    学习笔记
    mongorestore 命令行恢复 bson
    mysql 插数据 ,版本不一致 需要修改 utf8 COLLATE utf8_general_ci
  • 原文地址:https://www.cnblogs.com/bugzone/p/Volley.html
Copyright © 2011-2022 走看看