谷歌Volley网络框架分析。(一)初始化

技术水平有限,文章中所描述的错误,请帮助指出。多谢。

Volley提供的功能

简单的讲,提供了如下主要的功能:

1、封装了的异步的RESTful 请求API;

2、一个优雅和稳健的请求队列;

3、一个可扩展的架构,它使开发人员能够实现自定义的请求和响应处理机制;

4、能够使用外部HTTP Client库;

5、缓存策略;

6、自定义的网络图像加载视图(NetworkImageView,ImageLoader等);

7、Volley可以绑定Content的生命周期,例如当Activity销毁时,Volley可以取消响应的网络请求。

StringRequest

       这个类可以用来从服务器获取String,如果想自己解析请求响应可以使用这个类,例如返回xml数据。它还可以使用重载的构造函数定制请求。

[java]  view plain copy print ?
  1. final String URL = "/volley/resource/recent.xml";  
  2. StringRequest req = new StringRequest(URL, new Response.Listener<String>() {  
  3.     @Override  
  4.     public void onResponse(String response) {  
  5.         VolleyLog.v("Response:%n %s", response);  
  6.     }  
  7. }, new Response.ErrorListener() {  
  8.     @Override  
  9.     public void onErrorResponse(VolleyError error) {  
  10.         VolleyLog.e("Error: ", error.getMessage());  
  11.     }  
  12. });  
  13.   
  14. // add the request object to the queue to be executed  
  15. ApplicationController.getInstance().addToRequestQueue(req);  

在添加请求的时候首先创建一个网络请求队列RequestQueue,这应该是核心的请求队列。

Volley只是一个Helper类,帮助创建RequestQueue,

     */
    public RequestQueue getRequestQueue() {
        // lazy initialize the request queue, the queue instance will be
        // created when it is accessed for the first time
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }



newRequestQueue的具体实现代码:

             // 在2.3之前的版本,建议使用apache的HttpClient来处理网络请求,在2.3之后的版本建议使用HttpUrlConnection
            // 请参考:http://blog.csdn.net/forever_crying/article/details/7021174

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
            	// 在2.3之前的版本,建议使用apache的HttpClient来处理网络请求,在2.3之后的版本建议使用HttpUrlConnection
            	// 请参考:http://blog.csdn.net/forever_crying/article/details/7021174
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();

        return queue;
    }

Vooley初始化流程:

画了一个初始化的UML图,没学过UML,随便画画,另外求UML的学习书籍,真心不会画啊。。

大概是:Volley.newRequestQueue(),初始化网络请求队列,然后add()消息到RequestQueue,NetworkDispatcher分发消息到NetWork调用HttpStack请求网络,提交本地缓存信息到请求头,NetWork封装HttpStack返回数据,判断是否使用缓存,或者抛出相关的异常。

谷歌Volley网络框架分析。(一)初始化_第1张图片


相关注释:

1、Volley是一个Helper类,主要负责创建出请求队列,并且启动队列消息的循环。

2、HttpStack负责解析网络请求,performRequest返回一个Apache的HttpResponse,确保返回的Response有StatusLine
注:在2.3之前的版本,建议使用apache的HttpClient来处理网络请求,在2.3之后的版本建议使用HttpUrlConnection
http://blog.csdn.net/forever_crying/article/details/7021174

HurlStack,使用HttpUrlConnection,解析网络请求;HttpClientStack使用HttpClient解析网络请求

3、Network封装了HttpStack的网络请求,performRequest方法直接返回一个NetworkResponse,处理了请求异常抛出VolleyError。

4、NetworkDispatcher网络调度(线程池),分发网络请求到NetWork。


    /**
     * RequestQueue.start() 启动缓存调度和网络调度
     */
    public void start() {
        stop();  // Make sure any currently running dispatchers are stopped.
        // Create the cache dispatcher and start it.
        mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
        mCacheDispatcher.start();

        // Create network dispatchers (and corresponding threads) up to the pool size.
        for (int i = 0; i < mDispatchers.length; i++) {
            NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
                    mCache, mDelivery);
            mDispatchers[i] = networkDispatcher;
            networkDispatcher.start();
        }
    }


//BaseNetWork的主要代码 添加了一些注释
@Override
    public NetworkResponse performRequest(Request<?> request) throws VolleyError {
        long requestStart = SystemClock.elapsedRealtime();
        while (true) {
            HttpResponse httpResponse = null;
            byte[] responseContents = null;
            Map<String, String> responseHeaders = new HashMap<String, String>();
            try {
                // Gather headers.
                Map<String, String> headers = new HashMap<String, String>();//请求头信息。
                addCacheHeaders(headers, request.getCacheEntry());//添加本地缓存头信息
                httpResponse = mHttpStack.performRequest(request, headers);//发出网络请求
                StatusLine statusLine = httpResponse.getStatusLine();
                int statusCode = statusLine.getStatusCode();//HTTP状态码

                responseHeaders = convertHeaders(httpResponse.getAllHeaders());//解析头信息
                // Handle cache validation.
                if (statusCode == HttpStatus.SC_NOT_MODIFIED) {//可以使用缓存数据
                    return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED,
                            request.getCacheEntry().data, responseHeaders, true);
                }

                // Some responses such as 204s do not have content.  We must check.
                if (httpResponse.getEntity() != null) {//将返回数据 转化为byte数据
                  responseContents = entityToBytes(httpResponse.getEntity());
                } else {//如果没有返回内容。
                  // Add 0 byte response as a way of honestly representing a
                  // no-content request.
                  responseContents = new byte[0];
                }

                // if the request is slow, log it.
                long requestLifetime = SystemClock.elapsedRealtime() - requestStart;
                //如果请求时间过长 则打印Log
                logSlowRequests(requestLifetime, request, responseContents, statusLine);

                if (statusCode < 200 || statusCode > 299) {//服务器返回异常 则抛出IOException
                    throw new IOException();
                }
                return new NetworkResponse(statusCode, responseContents, responseHeaders, false);
            } catch (SocketTimeoutException e) {//链接超时 尝试重新链接 如果达到尝试次数 则会抛出VolleyError异常,此次请求则结束。
                attemptRetryOnException("socket", request, new TimeoutError());
            } catch (ConnectTimeoutException e) {//链接超时 尝试重新链接 如果达到尝试次数 则会抛出VolleyError异常,此次请求则结束。
                attemptRetryOnException("connection", request, new TimeoutError());
            } catch (MalformedURLException e) {//Bad URL
                throw new RuntimeException("Bad URL " + request.getUrl(), e);
            } catch (IOException e) {
                int statusCode = 0;
                NetworkResponse networkResponse = null;
                if (httpResponse != null) {
                    statusCode = httpResponse.getStatusLine().getStatusCode();
                } else {//{//如果没有返回httpResponse,就说明没连接
                    throw new NoConnectionError(e);
                }
                VolleyLog.e("Unexpected response code %d for %s", statusCode, request.getUrl());
                if (responseContents != null) {
                    networkResponse = new NetworkResponse(statusCode, responseContents,
                            responseHeaders, false);
                    if (statusCode == HttpStatus.SC_UNAUTHORIZED ||
                            statusCode == HttpStatus.SC_FORBIDDEN) {//认证失败异常,重试
                        attemptRetryOnException("auth",
                                request, new AuthFailureError(networkResponse));
                    } else {//服务器异常
                        // TODO: Only throw ServerError for 5xx status codes.
                        throw new ServerError(networkResponse);
                    }
                } else {//网络异常
                    throw new NetworkError(networkResponse);
                }
            }
        }
    }


你可能感兴趣的:(谷歌Volley网络框架分析。(一)初始化)