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
- Volley网络请求框架分析
- 网络请求框架---Volley
- Volley网络请求框架
- 网络请求框架---Volley
- 网络请求框架-Volley
- Volley-----网络请求框架
- Volley网络请求框架
- Volley网络请求框架
- Volley网络请求框架
- Android网络请求框架 Volley
- Android网络请求框架Volley
- Volley 框架 网络请求工具
- Android网络请求框架Volley
- Android Volley网络请求框架
- Volley网络请求数据框架
- Android网络请求框架-----Volley
- 网络请求篇---Volley框架
- 解剖网络请求框架Volley
- jsp小结07 - 7个动作指令04 plugin、param
- 懒加载详解
- Object-C系列-<push and pop>
- IOS开发基础Object-C(05)—OC变量的作用域、self
- poj2184(推荐)
- Volley网络请求框架分析
- C语言数据结构之栈与队列的应用(1)进制转换
- Android studio 多渠道打包(超简洁版)
- 折腾之重装linux
- C#:妥协与取舍,解构C#中的小数运算
- Script标签和脚本执行顺序
- 用MATLAB制作GIF
- 关于人工智能的二十件事
- 用递归反转stack里面的元素