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

来源:互联网 发布:天锐数据安全软件 编辑:程序博客网 时间:2024/06/05 12:44

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

Volley提供的功能

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

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

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

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

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

5、缓存策略;

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

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

StringRequest

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

[java] view plaincopyprint?
  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返回数据,判断是否使用缓存,或者抛出相关的异常。



相关注释:

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);                }            }        }    }


原创粉丝点击