时间:2015-04-28 来源:

GoogleVolley框架源码走读

PS一句:最终还是选择CSDN来整理发表这几年的知识点web前端制作,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,web前端制作牛逼啊!

@Override public void postResponse(Request<?> request, Runnable runnable) { request.markDelivered(); request.addMarker("post-response"); mResponsePoster.execute(new ResponseDeliveryRunnable(request, runnable)); } 这里可以看见在mResponsePoster的execute()方法中传入了一个ResponseDeliveryRunnable对象符合w3c标准,就可以保证该对象中的run()方法就是在主线程当中运行的了,符合w3c标准我们看下run()方法中的代码是什么样的:

还是按照前边的顺序分析吧网页外包接活,使用Volley的第一步首先是通过Volley.newRequestQueue(context)得到RequestQueue队列,jpg或psd转html那么先看下toolbox下的Volley.java中的这个方法吧.

走读代码时参考博客链接

/** * Adds a Request to the dispatch queue. * @param request The request to service * @return The passed-in request */ public <T> Request<T> add(Request<T> request) { // Tag the request as belonging to this queue and add it to the set of current requests. request.setRequestQueue(this); synchronized (mCurrentRequests) { mCurrentRequests.add(request); } // Process requests in the order they are added. request.setSequence(getSequenceNumber()); request.addMarker("add-to-queue"); // If the request is uncacheable, stagedRequests); if (VolleyLog.DEBUG) { VolleyLog.v("Request for cacheKey=%s is in flight, cacheKey); } } else { // Insert 'null' queue for this cacheKey, null); mCacheQueue.add(request); } return request; } } 可以看到注释所示符合w3c标准,添加一个Request到派发队列.Request是所有请求的基类,符合w3c标准是一个抽象类.request.setRequestQueue(this);的作用就是将请求Request关联到当前RequestQueue.然后同步操作将当前Request添加到RequestQueue对象的mCurrentRequests HashSet中做记录.通过request.setSequence(getSequenceNumber());得到当前RequestQueue中请求的个数网页外包接活,然后关联到当前Request.request.addMarker("add-to-queue");添加调试的Debug标记.if (!request.shouldCache())判断当前的请求是否可以缓存,网页外包接活如果不能缓存则直接通过mNetworkQueue.add(request);将这条请求加入网络请求队列web前端制作,然后返回request;如果可以缓存的话则在通过同步操作将这条请求加入缓存队列.在默认情况下,div+css制作每条请求都是可以缓存的承接网页制作,那么既然默认每条请求都是可以缓存的(shouldCache返回为true),自然就被添加到了缓存队列中,手机html制作于是一直在后台等待的缓存线程就要开始运行起来了.现在来看下CacheDispatcher中的run()方法符合w3c标准,代码如下所示:

在Android Developer上看到的这幅图:

Volley GitHub Demo:在GitHub主页搜索Volley会有很多,html切图制作不过建议阅读Android Developer文档.

NetWork接口的代码:

// Deliver a normal response or error, depending. if (mResponse.isSuccess()) { mRequest.deliverResponse(mResponse.result); } else { mRequest.deliverError(mResponse.error); } 这段代码是最核心的,网页外包接活明显可以看到通过mRequest的deliverResponse或者deliverError将反馈发送到回调到UI线程.这也是你重写实现的接口方法.

如上HttpStack创建完成之后创建了Network实例.BasicNetwork是Network接口的实现web前端制作,他们都在toolbox中,web前端制作BasicNetwork实现了public NetworkResponse performRequest(Request<?> request)方法承接网页制作,其作用是根据传入的HttpStack对象来处理网络请求.紧接着new出一个RequestQueue对象,div前端切图并调用它的start()方法进行启动web切图报价,然后将RequestQueue返回.RequestQueue是根目录下的一个类,手机html制作其作用是一个请求调度队列调度程序的线程池.这样newRequestQueue()的方法就执行结束了.

硬着头皮开始吧 直接这么看好空洞符合w3c标准,所以直接把clone的工程导入IDE边看代码边看这个图吧.

将请求Request add到RequestQueue后对于不需要缓存的请求(需要额外设置,符合w3c标准默认是需要缓存)直接丢入mNetworkQueue交给N个NetworkDispatcher处理;对于需要缓存的网页外包接活,新的请求加到mCacheQueue中给CacheDispatcher处理;需要缓存,jpg或psd转html但是缓存列表中已经存在了相同URL的请求web前端制作,放在mWaitingQueue中做暂时处理,web前端制作等待之前请求完毕后承接网页制作,再重新添加到mCacheQueue中.

Volley仓库:git clone https://android.googlesource.com/platform/frameworks/volley

接下来由while (true)可以发现缓存线程是一直在执行,承接网页制作其中通过mQuit标记进制是否结束线程的操作.mCacheQueue.take()从阻塞队列获取最前面的一个request,没有request就阻塞等待.接着通过mCache.get(request.getCacheKey());尝试从缓存中取出响应结果,网站div+css如何为空的话则把这条请求加入到网络请求队列中符合w3c标准,如果不为空的话再判断该缓存是否已过期,符合w3c标准如果已经过期了则同样把这条请求加入到网络请求队列中网页外包接活,否则就认为不需要重发网络请求,网页外包接活直接使用缓存中的数据即可.在这个过程中调运了parseNetworkResponse()方法来对数据进行解析web前端制作,再往后就是将解析出来的数据进行回调了.现在先来看下Request抽象基类的这部分代码:

Delivery分发者实际上已经是对网络请求处理的最后一层了,div+css制作在Delivery对请求处理之前承接网页制作,Request已经对网络应答进行过解析,承接网页制作此时应答成功与否已经设定;而后Delivery根据请求所获得的应答情况做不同处理;若应答成功web切图报价,则触发deliverResponse方法,手机html制作最终会触发开发者为Request设定的Listener;若应答失败符合w3c标准,则触发deliverError方法,html切图制作最终会触发开发者为Request设定的ErrorListener;处理完后网页外包接活,一个Request的生命周期就结束了,网页外包接活Delivery会调用Request的finish操作web前端制作,将其从mRequestQueue中移除,web前端制作与此同时承接网页制作,如果等待列表中存在相同URL的请求,div前端切图则会将剩余的层级请求全部丢入mCacheQueue交由CacheDispatcher进行处理.

再来整体看下 现在是该回过头去看背景知识模块了web切图报价,再看下那幅官方图,手机html制作对比就明白咋回事了.结合上图和如上分析可以知道:

/** * Starts the dispatchers in this queue. */ public void start() { stop(); // Make sure any currently running dispatchers are stopped. // Create the cache dispatcher and start it. mCacheDispatcher = new CacheDispatcher(mCacheQueue, mCache, mNetwork, mDelivery); mDispatchers[i] = networkDispatcher; networkDispatcher.start(); } } 通过注释可以看出来这里在派发队列的事务.先是创建了一个CacheDispatcher的实例承接网页制作,然后调用了它的start()方法,承接网页制作接着在一个for循环里去创建NetworkDispatcher的实例web切图报价,并分别调用它们的start()方法.这里的CacheDispatcher和NetworkDispatcher都是继承自Thread的,网站div+css而默认情况下for循环会执行(DEFAULT_NETWORK_THREAD_POOL_SIZE)四次符合w3c标准,也就是说当调用了Volley.newRequestQueue(context)之后,符合w3c标准就会有五个线程一直在后台运行网页外包接活,不断等待网络请求的到来,网页外包接活其中一个CacheDispatcher是缓存线程web前端制作,四个NetworkDispatcher是网络请求线程.

按照之前使用Volley可以知道,div+css制作得到了RequestQueue之后承接网页制作,然后调用RequestQueue的add()方法将Request传入就可以完成网络请求操作了.也就是说add()方法的内部是核心代码了.现在看下RequestQueue的add方法web切图报价, blocking until // at least one is available. final Request<?> request = mCacheQueue.take(); request.addMarker("cache-queue-take"); // If the request has been canceled, just send it to the network. if (entry.isExpired()) { request.addMarker("cache-hit-expired"); request.setCacheEntry(entry); mNetworkQueue.put(request); continue; } // We have a cache hit; parse its data for delivery back to the request. request.addMarker("cache-hit"); Response<?> response = request.parseNetworkResponse( new NetworkResponse(entry.data, response); } else { // Soft-expired cache hit. We can deliver the cached response, response, new Runnable() { @Override public void run() { try { mNetworkQueue.put(request); } catch (InterruptedException e) { // Not much we can do about this. } } }); } } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } } } 首先通过Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);设置线程优先级,div前端切图然后通过mCache.initialize(); 初始化缓存块web切图报价, HttpStack stack)方法中实例化传入的符合w3c标准,其中cacheDir默认在Volley.java中不设置为/data/data/app-package/cache/volley/.

RequestQueue会维护一个缓存调度线程(cache线程)和一个网络调度线程池(net线程),当一个Request被加到队列中的时候,jpg或psd转htmlcache线程会把这个请求进行筛选:如果这个请求的内容可以在缓存中找到web前端制作,cache线程会亲自解析相应内容,web前端制作并分发到主线程(UI).如果缓存中没有承接网页制作,所有真正准备进行网络通信的request都在这里web切图报价,第一个可用的net线程会从NetworkQueue中拿出一个request扔向服务器.当响应数据到的时候,网站div+css这个net线程会解析原始响应数据符合w3c标准,写入缓存,符合w3c标准并把解析后的结果返回给主线程.

@Override public NetworkResponse performRequest(Request<?> request) throws VolleyError { long requestStart = SystemClock.elapsedRealtime(); while (true) { HttpResponse httpResponse = null; byte[] responseContents = null; Map<String, String> headers = new HashMap<String, request.getCacheEntry()); httpResponse = mHttpStack.performRequest(request, null, true, entry.data, true, log it. long requestLifetime = SystemClock.elapsedRealtime() - requestStart; logSlowRequests(requestLifetime, responseContents, responseContents, false, request, request, e); } catch (IOException e) { int statusCode = 0; NetworkResponse networkResponse = null; if (httpResponse != null) { statusCode = httpResponse.getStatusLine().getStatusCode(); } else { throw new NoConnectionError(e); } VolleyLog.e("Unexpected response code %d for %s", request.getUrl()); if (responseContents != null) { networkResponse = new NetworkResponse(statusCode, responseHeaders, SystemClock.elapsedRealtime() - requestStart); if (statusCode == HttpStatus.SC_UNAUTHORIZED || statusCode == HttpStatus.SC_FORBIDDEN) { attemptRetryOnException("auth", new AuthFailureError(networkResponse)); } else { // TODO: Only throw ServerError for 5xx status codes. throw new ServerError(networkResponse); } } else { throw new NetworkError(networkResponse); } } } } 这个方法是网络请求的具体实现承接网页制作,也是一个大while循环,承接网页制作其中mHttpStack.performRequest(request, headers);代码中的mHttpStack是Volley的newRequestQueue()方法中创建的实例,手机html制作前面已经说过符合w3c标准,这两个对象的内部实际就是分别使用HttpURLConnection和HttpClient来发送网络请求的,html切图制作然后把服务器返回的数据组装成一个NetworkResponse对象进行返回.在NetworkDispatcher中收到了NetworkResponse这个返回值后又会调用Request的parseNetworkResponse()方法来解析NetworkResponse中的数据网页外包接活,同时将数据写入到缓存,网页外包接活这个方法的实现是交给Request的子类来完成的web前端制作, or null in the case of an error */ abstract protected Response<T> parseNetworkResponse(NetworkResponse response); 通过注释可以看到他就是一个解析模块的功能.

至此所有搞定.

public interface Network { /** * Performs the specified request. * @param request Request to process * @return A {@link NetworkResponse} with data and caching metadata; will never be null * @throws VolleyError on errors */ public NetworkResponse performRequest(Request<?> request) throws VolleyError; } 上面说了承接网页制作, response);,也就是说在解析完了NetworkResponse中的数据之后,手机html制作又会调用ExecutorDelivery(ResponseDelivery接口的实现类)的postResponse()方法来回调解析出的数据符合w3c标准, or null for default. * @return A started {@link RequestQueue} instance. */ public static RequestQueue newRequestQueue(Context context, DEFAULT_CACHE_DIR); String userAgent = "volley/0"; try { String packageName = context.getPackageName(); PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 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; } 如上所示,承接网页制作该方法有两个参数web切图报价,第一个Context是为了拿到当前App的Activity的一些信息,网站div+css第二个参数在默认的RequestQueue newRequestQueue(Context context)方法中传递为null,也就是说在这段代码中的if (stack == null)会被执行.在这个if中对版本号进行了判断,符合w3c标准如果版本号大于等于9就使得HttpStack对象的实例为HurlStack,如果小于9则实例为HttpClientStack.至于这里为何进行版本号判断,网页外包接活实际代码中的(Click Me To See)注释已经说明了.实际上HurlStack类也在toolbox中web前端制作, Map<String, String> additionalHeaders)方法,承接网页制作其实现过程使用的是HttpURLConnection.而HttpClientStack也在toolbox中web切图报价, Map<String, String> additionalHeaders)方法,html切图制作不过其实现过程使用的是HttpClient而已.

上面说了网页外包接活,当调用了Volley.newRequestQueue(context)之后,网页外包接活就会有五个线程一直在后台运行web前端制作,不断等待网络请求的到来,web前端制作其中一个CacheDispatcher是缓存线程承接网页制作,四个NetworkDispatcher是网络请求线程.CacheDispatcher的run方法刚才已经大致分析了,div前端切图解析来看下NetworkDispatcher中是怎么处理网络请求队列的web切图报价,具体代码如下所示:

背景知识 在Volley使用基础那一篇最后一个知识点说到了Volley的请求架构,手机html制作这里再搬过来说说.

CacheDispatcher缓存调度器最为第一层缓冲符合w3c标准,开始工作后阻塞的从缓存序列mCacheQueue中取得请求;对于已经取消的请求,符合w3c标准标记为跳过并结束这个请求;新的或者过期的请求网页外包接活,直接放入mNetworkQueue中由N个NetworkDispatcher进行处理;已获得缓存信息(网络应答)却没有过期的请求,jpg或psd转html由Request的parseNetworkResponse进行解析web前端制作,从而确定此应答是否成功.然后将请求和应答交由Delivery分发者进行处理,web前端制作如果需要更新缓存那么该请求还会被放入mNetworkQueue中.

@Override public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); while (true) { long startTimeMs = SystemClock.elapsedRealtime(); Request<?> request; try { // Take a request from the queue. request = mQueue.take(); } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } try { request.addMarker("network-queue-take"); // If the request was cancelled already, // we're done -- don't deliver a second identical response. if (networkResponse.notModified && request.hasHadResponseDelivered()) { request.finish("not-modified"); continue; } // Parse the response here on the worker thread. Response<?> response = request.parseNetworkResponse(networkResponse); request.addMarker("network-parse-complete"); // Write to cache if applicable. // TODO: Only update cache metadata instead of entire record for 304s. if (request.shouldCache() && response.cacheEntry != null) { mCache.put(request.getCacheKey(), response); } catch (VolleyError volleyError) { volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs); parseAndDeliverNetworkError(request, "Unhandled exception %s", volleyError); } } } 和CacheDispatcher差不多web前端制作,如上可以看见一个类似的while(true)循环,div+css制作说明网络请求线程也是在不断运行的.

PPPS一句:通过上面原理分析之后总结发现承接网页制作,推荐整个App全局持有一个RequestQueue的做法,承接网页制作这样会有相对比较高的性能效率.

其中的userAgent就是App的包名加版本号而已web切图报价,传入new HttpClientStack(AndroidHttpClient.newInstance(userAgent));作为name TAG使用.

当一个RequestQueue被成功申请后会开启一个CacheDispatcher和4个默认的NetworkDispatcher.

现在再来看下根目录下RequestQueue队列的start方法,手机html制作如下所示:

/** * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it. * * @param context A {@link Context} to use for creating the cache dir. * @return A started {@link RequestQueue} instance. */ public static RequestQueue newRequestQueue(Context context) { return newRequestQueue(context, null); } 先看如上注释所示,html切图制作创建一个默认的worker pool,并且调运RequestQueue的start方法.在这个方法里又调运了该类的另一个连个参数的重载方法,网页外包接活如下所示.

开源项目链接 Volley自定义 Android Developer文档

网络请求调度器NetworkDispatcher作为网络请求真实发生的地方web前端制作,对消息交给BasicNetwork进行处理,web前端制作同样的承接网页制作, Response response, finish it and don't deliver. if (mRequest.isCanceled()) { mRequest.finish("canceled-at-delivery"); return; } // Deliver a normal response or error, add a marker, run it. if (mRunnable != null) { mRunnable.run(); } } } 这段代码里的run方法中可以看到如下一部分细节:

如上通过mNetwork.performRequest(request);代码来发送网络请求web前端制作,而Network是一个接口,web前端制作这里具体的实现之前已经分析是BasicNetwork,所以先看下它的performRequest()方法,承接网页制作如下所示:

$(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });

点击次数:23391
作者:
web前端行业资讯
Web new NewsList
英特尔宣布与法拉利跨界合作欲将AI技术用于赛车运动 ,,2018年01月11日甲骨文服务器出漏洞:攻击者用漏洞挖矿获取加密货币 ,,2018年01月11日用深度学习设计图像视频压缩算法:更简洁、更强大 ,,2018年01月11日Ubuntu内核和NVIDIA更新:修复Meltdown和Spectre两处漏洞 ,,2018年01月11日AntDesign3.1.1发布,阿里企业级UI设计语言 ,,2018年01月11日微信「跳一跳」带火小游戏,开发者如何快速上手? ,,2018年01月11日谷歌公布最新安卓系统份额:你用上奥利奥了么? ,,2018年01月11日腾讯开发出“3D音效”算法:普通耳机实现3D实时语音效果 ,,2018年01月11日谷歌工程师点赞中国程序员实现Node.js启动超4倍提速 ,,2018年01月11日三星电子总裁兼CE部门负责人金炫奭:万物互联时代到来 ,,2018年01月11日NVIDIA和大众合作建立智能驾驶助手 ,,2018年01月11日GIMPS项目报告发现已知最大素数 ,,2018年01月11日微软与生物技术公司开展AI驱动的血液检测同时诊断数十种疾病 ,,2018年01月11日微软跨平台移动开发工具套件HockeyApp宣布免费 ,,2018年01月11日《硅谷》里神乎其神的压缩技术,AI正在一点点做出来 ,,2018年01月11日LinuxMint19代号敲定为“Tara”预计2018年5月至6月期间发布 ,,2018年01月11日Facebook发布wav2letter工具包,用于端到端自动语音识别 ,,2018年01月11日开源数据库ArangoDB正进行约1156万美元股权融资 ,,2018年01月11日IntelCPU漏洞闹大:腾讯云紧急升级 ,,2018年01月11日2018年1月全球数据库排名:Redis夺回第八 ,,2018年01月11日Lyft将联手无人驾驶公司于CES上展示无人驾驶汽车 ,,2018年01月11日京东X无人超市首家社会门店开业:刷脸进、微信自动结算 ,,2018年01月11日担心被AI取代是杞人忧天?高晓松跨年演讲说的有几分对 ,,2018年01月11日免费授权技术许可Intel宣布在未来CPU中集成雷电3 ,,2018年01月11日算法决定你在社交媒体上看到的信息 ,,2018年01月11日谷歌安全博客披露“英特尔内核漏洞”更多细节 ,,2018年01月04日Postgres10开发者新特性 ,,2017年12月28日阿里巴巴、狗尾草、苏大联合论文:基于对抗学习的众包标注用于中文命名实体识别 ,,2017年12月28日柯洁的2017:20岁,与AI斗与人类斗,其乐无穷 ,,2017年12月28日如果机器人拥有痛觉,这个世界会有哪些不一样? ,,2017年12月28日注册表全面禁用控制面板【移动开发】2015年03月02日51nodround3#序列分解(折半枚举+字典树)【编程语言】2015年07月07日Nodejscluster模块深入探究2017年07月19日hdu_1031_DesignT-Shirt(模拟)2014年12月29日Android实现图片的倒影效果 【编程语言】2015年08月03日LeetCode165.CompareVersionNumbers 【Web前端】2015年03月17日JS复制内容到剪切板的实例代码(兼容IE与火狐)2014年01月29日【DWR】解决sessionerror问题 【编程语言】2015年01月12日JDK5新特性之线程同步集合(五)【移动开发】2014年11月04日x86内存映射 【综合】2014年11月24日Lua学习笔记之协同程序 【编程语言】2014年11月26日hdu-5313BipartiteGraph 【数据库】2015年07月31日Spinner(二)——简单使用完整示例【编程语言】2014年12月09日《变形金刚2》摩托女金刚阿尔茜亮相2014年01月28日JavaScript字符串与数组转换函数【不用split与join】2014年01月29日自动化部署MySQL5.6步骤【移动开发】2014年12月03日Javascript操作CSS学习笔记 【移动开发】2015年07月24日JQUERY获取当前页面的URL信息【移动开发】2015年03月26日Excel2007教程:数据输入技巧2014年01月28日杀死LinuxShell进程【系统运维】2015年08月17日蓝桥杯-分糖果(模拟~) 【编程语言】2015年03月11日图形循环渐显脚本2014年01月28日http返回状态码总结 【系统运维】2015年05月12日云计算设计模式(五)——计算资源整合模式【架构设计】2014年11月06日常用跨域资源请求分析2015年03月09日053第495题 【互联网】2015年07月14日PHP源文件加密工具PHPScrew ,,2016年07月24日leetcode笔记:SingleNumber 【移动开发】2015年09月05日Android中自定义对话框(Dialog)的实例代码2014年01月30日orgmode排版技巧 【数据库】2015年02月09日
我们保证
We guarantee
> psd效果文件手工切图,保证图片效果最好体积最小利于传输
> 100%手写的HTML(DIV+CSS)编码,绝对符合W3C标准
> 代码精简、css沉余量小、搜索引擎扫描迅速,网页打开快捷
> 应用Css Sprite能够减少HTTP请求数,提高网页性能
> 跨浏览器兼容(IE6、7、8、9,Firefox火狐,Chrome谷歌)