Volley网络请求框架分析

来源:互联网 发布:linux spawn 编辑:程序博客网 时间:2024/04/27 21:38
本文代码省略了许多个人认为不重要的内容,具体请参考volley源码

volley的入口在Volley.java的newRequestQueue方法中
    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 {                // 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;    }
上面的代码最主要的内容是在SDK>9的时候使用HttpUrlconnection,其他时候使用HttpClient(BTW: 据说HttpClient在android6.0上已经不能使用了)
最重要的代码是queue.start()
queue.start();   //初始化,开始接收网络请求    mCacheDispatcher.start();        mCache.initialize();   //缓存初始化        while(true)            if (request.isCanceled()) {    //请求是否取消                request.finish("cache-discard-canceled");  //执行finish            }            Cache.Entry entry = mCache.get(request.getCacheKey());   //尝试从缓存中获取            if (entry == null) {                mNetworkQueue.put(request);   //如果缓存中没有,添加到网络队列            }            if (entry.isExpired()) {        //检查缓存是否过期                request.setCacheEntry(entry);       //缓存已经过期,重用缓存实例,将缓存加入到网络队列中                mNetworkQueue.put(request);            }            //此时缓存已经命中,根据volley支持的几种网络请求(图片,json,string等)解析网络应答            Response<?> response = request.parseNetworkResponse(                new NetworkResponse(entry.data, entry.responseHeaders));            if (!entry.refreshNeeded()) { //根据httpHeader中的softTtl判断缓存是否需要刷新            //分配器交付此次网络应答            mDelivery.postResponse(request, response);            } else {            //根据softTtl设置来说,缓存已经过期,依旧可以交付此次网络应答,不过需要后台刷新此次请求            request.setCacheEntry(entry);            response.intermediate = true;            mDelivery.postResponse(request, response, new Runnable() {   //此次网络应答已经过期,虽然可以交付,但是需要进行刷新操作                    @Override                    public void run() {                        mNetworkQueue.put(request);                    }                });            }    networkDispatcher.start();        while (true)            request = mQueue.take();                if (request.isCanceled()) {  //请求已经取消                request.finish("network-discard-cancelled");            }            addTrafficStatsTag(request);  //统计流量使用            NetworkResponse networkResponse = mNetwork.performRequest(request);  //执行网络请求            while (true)             Map<String, String> responseHeaders = Collections.emptyMap(); //httpHeader            Map<String, String> headers = new HashMap<String, String>(); //cacheHeader            httpResponse = mHttpStack.performRequest(request, headers);  //网络请求核心部分,httpstack需要实现performRequest用于请求http应答            int statusCode = statusLine.getStatusCode(); //获取网络状态码            responseHeaders = convertHeaders(httpResponse.getAllHeaders()); //获取httpHeader            if (statusCode == HttpStatus.SC_NOT_MODIFIED) {            entry.responseHeaders.putAll(responseHeaders); //更新缓存的httpHeader            return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, entry.data,  //返回网络应答                            entry.responseHeaders, true,                            SystemClock.elapsedRealtime() - requestStart);            }            //处理部分网络entity为空的情况            if (httpResponse.getEntity() != null) {                  responseContents = entityToBytes(httpResponse.getEntity());                } else {responseContents = new byte[0];                }                //处理部分网络速度过慢问题                logSlowRequests(requestLifetime, request, responseContents, statusLine);                if (statusCode < 200 || statusCode > 299) { //在ioException中处理网络异常情况                    throw new IOException();                }                return new NetworkResponse(statusCode, responseContents, responseHeaders, false, //返回网络应答                        SystemClock.elapsedRealtime() - requestStart);             if (networkResponse.notModified && request.hasHadResponseDelivered()) { //返回304或者网络请求已经被处理                request.finish("not-modified");            }            Response<?> response = request.parseNetworkResponse(networkResponse); //解析网络应答            if (request.shouldCache() && response.cacheEntry != null) { //缓存网络应答                mCache.put(request.getCacheKey(), response.cacheEntry);            }            request.markDelivered(); //标记请求已经被处理        mDelivery.postResponse(request, response); //分配器交付此次网络应答

在start方法中默认创建了一个缓存线程和四个网络线程,分别对应着一个缓存队列一个网络队列,缓存线程和网络线程不停的从这两个队列中获取request并执行,那么这两个队列中的request从何而来的呢,答案是queue.add
queue.add();    mCurrentRequests.add(request);   //将请求添加到请求队列中,用于在cancel中取消    if (!request.shouldCache()) {    //如果不需要缓存直接加入网络队列中,否则加入缓存队列        mNetworkQueue.add(request);        return request;    }    if (mWaitingRequests.containsKey(cacheKey)) {   //如果等待队列中包含缓存的key,更新请求    Queue<Request<?>> stagedRequests = mWaitingRequests.get(cacheKey);      stagedRequests.add(request);        mWaitingRequests.put(cacheKey, stagedRequests);    } else {    mWaitingRequests.put(cacheKey, null);        mCacheQueue.add(request);    }

从add方法中可以看出除非request设置了不需要缓存,默认都会将request添加到缓存队列中去,然后由mCacheDispatcher来做下一步的处理

未完待续。。。

0 0
原创粉丝点击