电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

解析Android框架之Volley源碼

瀏覽:7日期:2022-09-18 11:08:11
目錄Volley簡單使用Volley執行原理Volley簡單使用

我這里是以依賴架包的形式 ,大家也可以以gradle的形式進行依賴。

解析Android框架之Volley源碼

好了,接下來上代碼了.....

//獲取volley的請求對象RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, 'http://www.baidu.com', new Response.Listener<String>() { @Override public void onResponse(String s) {Log.d('MainActivity', '----->' + s); }}, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) {Log.d('MainActivity', '---volleyError-->' + volleyError); }});requestQueue.add(stringRequest);

從代碼可以看出,首先newRequestQueue來獲取到一個請求隊列,然后在將StringRequest這個請求添加到請求隊列中,就可以了,就是這么簡單。當然請求不值StringRequest,還有JsonObjectRequest ,ImageRequest等等但是用法都是一樣的,這里就不貼代碼了。Volley的簡單使用就這樣可以進行請求了。是不是很簡單

Volley執行原理

但是這個不是本篇的重點,重點是分析一下這些是怎么執行的。先上一張圖

解析Android框架之Volley源碼

我們先看看newRequestQueue這個內部是怎么執行的,代碼一開始連續執行了幾個重載方法,最后走到newRequestQueue

public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes) { File cacheDir = new File(context.getCacheDir(), 'volley'); String userAgent = 'volley/0'; try {String packageName = context.getPackageName();PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);userAgent = packageName + '/' + info.versionCode; } catch (NameNotFoundException var7) {; } //這里進行了一個版本的判斷 2.3之前用的是HTTPClient,2.3之后使用的是HttpURLConnection if (stack == null) {if (VERSION.SDK_INT >= 9) { stack = new HurlStack();} else { stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));} } Network network = new BasicNetwork((HttpStack)stack); RequestQueue queue; if (maxDiskCacheBytes <= -1) {queue = new RequestQueue(new DiskBasedCache(cacheDir), network); } else {queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network); } queue.start(); return queue;}

在這里,我們看到了一個版本判斷,是不是瞬間感覺有點熟悉,沒錯,我們前面說的,volley2.3之前用的是HTTPClient,2.3之后使用的是HttpURLConnection就是在這里進行判斷的。接著看queue.start();

public void start() {this.stop();this.mCacheDispatcher = new CacheDispatcher(this.mCacheQueue, this.mNetworkQueue, this.mCache, this.mDelivery);this.mCacheDispatcher.start();for(int i = 0; i < this.mDispatchers.length; ++i) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(this.mNetworkQueue, this.mNetwork, this.mCache, this.mDelivery); this.mDispatchers[i] = networkDispatcher; networkDispatcher.start();} }

mCacheDispatcher是緩存調度線程,NetworkDispatcher是網絡調度線程,而這個this.mDispatchers.length系統默認的大小為4,也就是說,在這里總共啟動了5個線程在后臺運行。

好了,到這里,就可以了,看源碼不要每一行都弄懂,不然,出不來了。到這里就拿到了這個RequestQueue對象。回過頭來看前面使用的代碼

//獲取volley的請求對象RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, 'http://www.baidu.com', new Response.Listener<String>() { @Override public void onResponse(String s) {Log.d('MainActivity', '----->' + s); }}, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) {Log.d('MainActivity', '---volleyError-->' + volleyError); }});requestQueue.add(stringRequest);

我們拿到這個RequestQueue對象以后,然后就把這個請求通過add方法添加到隊列中,我們看看這個add()方法是怎么執行的。

public <T> Request<T> add(Request<T> request) {request.setRequestQueue(this);Set var2 = this.mCurrentRequests;synchronized(this.mCurrentRequests) { this.mCurrentRequests.add(request);}request.setSequence(this.getSequenceNumber());request.addMarker('add-to-queue');if (!request.shouldCache()) { //如果不能緩存 this.mNetworkQueue.add(request); return request;} else { Map var7 = this.mWaitingRequests; synchronized(this.mWaitingRequests) {String cacheKey = request.getCacheKey();if (this.mWaitingRequests.containsKey(cacheKey)) { //判斷之前是否執行過,但是還沒有返回結果 Queue<Request<?>> stagedRequests = (Queue)this.mWaitingRequests.get(cacheKey); if (stagedRequests == null) {stagedRequests = new LinkedList(); } ((Queue)stagedRequests).add(request); this.mWaitingRequests.put(cacheKey, stagedRequests); if (VolleyLog.DEBUG) {VolleyLog.v('Request for cacheKey=%s is in flight, putting on hold.', new Object[]{cacheKey}); }} else {//沒有的話就將請求加入緩存隊列mCacheQueue,同時加入mWaitingRequests中用來做下次同樣請求來時的重復判斷依據 this.mWaitingRequests.put(cacheKey, (Object)null); this.mCacheQueue.add(request);}return request; }} }

從代碼中可以看出,首先判斷是否可以緩存,當然,默認是可以緩存的。如果不能緩存的話,則通過this.mNetworkQueue.add(request);將請求添加到網絡請求隊列中。如果可以緩存,則還會判斷一次這個請求是否請求,如果執行過就就通過this.mWaitingRequests.put(cacheKey, stagedRequests);添加到mWaitingRequests隊列,不在重復請求。否則就加入到緩存隊列。

大體的流程是這樣。現在我們看看緩存的,和網絡的是怎么執行的。我們找到start()方法

public void start() {this.stop();this.mCacheDispatcher = new CacheDispatcher(this.mCacheQueue, this.mNetworkQueue, this.mCache, this.mDelivery);this.mCacheDispatcher.start();for(int i = 0; i < this.mDispatchers.length; ++i) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(this.mNetworkQueue, this.mNetwork, this.mCache, this.mDelivery); this.mDispatchers[i] = networkDispatcher; networkDispatcher.start();} }

先看CacheDispatcher,找到run()方法

public void run() {if (DEBUG) { VolleyLog.v('start new dispatcher', new Object[0]);}Process.setThreadPriority(10);this.mCache.initialize();while(true) { while(true) {while(true) { while(true) {try { while(true) {final Request<?> request = (Request)this.mCacheQueue.take(); //從緩存隊列中獲取到一個請求request.addMarker('cache-queue-take');if (request.isCanceled()) { //判斷請求是否取消,如果取消了,那就將該請求finish掉 request.finish('cache-discard-canceled');} else { Entry entry = this.mCache.get(request.getCacheKey()); if (entry == null) {//如果從緩存中取出來的內容為空,則將請求加入到網絡線程中再次請求request.addMarker('cache-miss');this.mNetworkQueue.put(request); } else if (entry.isExpired()) { //如果請求過期了,則將請求加入到網絡線程中再次請求request.addMarker('cache-hit-expired');request.setCacheEntry(entry);this.mNetworkQueue.put(request); } else { //將數據回調到主線程request.addMarker('cache-hit');Response<?> response = request.parseNetworkResponse(new NetworkResponse(entry.data, entry.responseHeaders));request.addMarker('cache-hit-parsed');if (entry.refreshNeeded()) { request.addMarker('cache-hit-refresh-needed'); request.setCacheEntry(entry); response.intermediate = true; this.mDelivery.postResponse(request, response, new Runnable() {public void run() {try { CacheDispatcher.this.mNetworkQueue.put(request);} catch (InterruptedException var2) { ;}} });} else { this.mDelivery.postResponse(request, response);} }} }} catch (InterruptedException var4) { if (this.mQuit) {return; }} }} }} }

這里嵌套了幾個循環,有點凌亂啊,但是慢慢分析的話,就會發現,其實很清晰。我在注釋上面寫了,這里就不重復了

我們在看看NetworkDispatcher,看看網絡線程是怎么執行的。一樣找到run()方法

public void run() {Process.setThreadPriority(10);while(true) { long startTimeMs; Request request; while(true) {startTimeMs = SystemClock.elapsedRealtime();try { request = (Request)this.mQueue.take(); //獲取到一個請求 break;} catch (InterruptedException var6) { if (this.mQuit) {return; }} } try {request.addMarker('network-queue-take');if (request.isCanceled()) { //如果請求取消了,則將請求finish掉 request.finish('network-discard-cancelled');} else {//進行網絡請求 this.addTrafficStatsTag(request); NetworkResponse networkResponse = this.mNetwork.performRequest(request); request.addMarker('network-http-complete'); if (networkResponse.notModified && request.hasHadResponseDelivered()) {request.finish('not-modified'); } else {Response<?> response = request.parseNetworkResponse(networkResponse);request.addMarker('network-parse-complete');if (request.shouldCache() && response.cacheEntry != null) { this.mCache.put(request.getCacheKey(), response.cacheEntry); request.addMarker('network-cache-written');}request.markDelivered();this.mDelivery.postResponse(request, response); }} } catch (VolleyError var7) {var7.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);this.parseAndDeliverNetworkError(request, var7); } catch (Exception var8) {VolleyLog.e(var8, 'Unhandled exception %s', new Object[]{var8.toString()});VolleyError volleyError = new VolleyError(var8);volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);this.mDelivery.postError(request, volleyError); }} }

代碼比較多,我們直接找到NetworkResponse networkResponse = this.mNetwork.performRequest(request);這句代碼,這句代碼就是請求網絡的代碼,最核心的。performRequest是一個接口,我們看看這個performRequest()方法。Network在最開始說版本判斷的時候里面有一句代碼Network network = new BasicNetwork((HttpStack)stack); 從這句代碼,我們可以知道BasicNetwork才是最終實現網絡請求的類,我們找到performRequest方法

public NetworkResponse performRequest(Request<?> request) throws VolleyError {long requestStart = SystemClock.elapsedRealtime();while(true) { HttpResponse httpResponse = null; byte[] responseContents = null; Map responseHeaders = Collections.emptyMap(); try {Map<String, String> headers = new HashMap();this.addCacheHeaders(headers, request.getCacheEntry());httpResponse = this.mHttpStack.performRequest(request, headers);StatusLine statusLine = httpResponse.getStatusLine();int statusCode = statusLine.getStatusCode();responseHeaders = convertHeaders(httpResponse.getAllHeaders());if (statusCode == 304) { Entry entry = request.getCacheEntry(); if (entry == null) {return new NetworkResponse(304, (byte[])null, responseHeaders, true, SystemClock.elapsedRealtime() - requestStart); } entry.responseHeaders.putAll(responseHeaders); return new NetworkResponse(304, entry.data, entry.responseHeaders, true, SystemClock.elapsedRealtime() - requestStart);}if (statusCode == 301 || statusCode == 302) { String newUrl = (String)responseHeaders.get('Location'); request.setRedirectUrl(newUrl);}byte[] responseContents;if (httpResponse.getEntity() != null) { responseContents = this.entityToBytes(httpResponse.getEntity());} else { responseContents = new byte[0];}long requestLifetime = SystemClock.elapsedRealtime() - requestStart;this.logSlowRequests(requestLifetime, request, responseContents, statusLine);if (statusCode >= 200 && statusCode <= 299) { return new NetworkResponse(statusCode, responseContents, responseHeaders, false, SystemClock.elapsedRealtime() - requestStart);}throw new IOException(); } catch (SocketTimeoutException var12) {attemptRetryOnException('socket', request, new TimeoutError()); } catch (ConnectTimeoutException var13) {attemptRetryOnException('connection', request, new TimeoutError()); } catch (MalformedURLException var14) {throw new RuntimeException('Bad URL ' + request.getUrl(), var14); } catch (IOException var15) {int statusCode = false;NetworkResponse networkResponse = null;if (httpResponse == null) { throw new NoConnectionError(var15);}int statusCode = httpResponse.getStatusLine().getStatusCode();if (statusCode != 301 && statusCode != 302) { VolleyLog.e('Unexpected response code %d for %s', new Object[]{statusCode, request.getUrl()});} else { VolleyLog.e('Request at %s has been redirected to %s', new Object[]{request.getOriginUrl(), request.getUrl()});}if (responseContents == null) { throw new NetworkError(networkResponse);}networkResponse = new NetworkResponse(statusCode, (byte[])responseContents, responseHeaders, false, SystemClock.elapsedRealtime() - requestStart);if (statusCode != 401 && statusCode != 403) { if (statusCode != 301 && statusCode != 302) {throw new ServerError(networkResponse); } attemptRetryOnException('redirect', request, new AuthFailureError(networkResponse));} else { attemptRetryOnException('auth', request, new AuthFailureError(networkResponse));} }} }

代碼比較多,但是大多數代碼是判斷狀態返回碼的,不需要理會。

我們直接看httpResponse = this.mHttpStack.performRequest(request, headers);這一句代碼,HttpStack這個有沒有很熟悉。沒有??沒關系我在復制一次代碼

if (stack == null) { if (VERSION.SDK_INT >= 9) {stack = new HurlStack(); } else {stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); }}

還是在這個版本判斷這里,這里就是HurlStack就是真正的網絡請求的類了,網絡請求,就是寫在這個類里面的。好了,volley整個流程大概就是這樣了。現在大家回過頭看最初的哪一張圖,是不是明了很多。

以上就是解析Android框架之Volley源碼的詳細內容,更多關于Android框架之Volley源碼的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
主站蜘蛛池模板: 悬浮拼装地板_幼儿园_篮球场_悬浮拼接地板-山东悬浮拼装地板厂家 | 磁力去毛刺机_去毛刺磁力抛光机_磁力光饰机_磁力滚抛机_精密金属零件去毛刺机厂家-冠古科技 | 流量卡中心-流量卡套餐查询系统_移动电信联通流量卡套餐大全 | 深圳标识制作公司-标识标牌厂家-深圳广告标识制作-玟璟广告-深圳市玟璟广告有限公司 | MTK核心板|MTK开发板|MTK模块|4G核心板|4G模块|5G核心板|5G模块|安卓核心板|安卓模块|高通核心板-深圳市新移科技有限公司 | 微信聊天记录恢复_手机短信删除怎么恢复_通讯录恢复软件下载-快易数据恢复 | 硬度计,金相磨抛机_厂家-莱州华煜众信试验仪器有限公司 | 济南律师,济南法律咨询,山东法律顾问-山东沃德律师事务所 | 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 假肢-假肢价格-假肢厂家-河南假肢-郑州市力康假肢矫形器有限公司 | 物联网卡_物联网卡购买平台_移动物联网卡办理_移动联通电信流量卡通信模组采购平台? | 层流手术室净化装修-检验科ICU改造施工-华锐净化工程-特殊科室建设厂家 | 注塑模具_塑料模具_塑胶模具_范仕达【官网】_东莞模具设计与制造加工厂家 | 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 电动卫生级调节阀,电动防爆球阀,电动软密封蝶阀,气动高压球阀,气动对夹蝶阀,气动V型调节球阀-上海川沪阀门有限公司 | 澳威全屋定制官网|极简衣柜十大品牌|衣柜加盟代理|全屋定制招商 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 带式过滤机厂家_价格_型号规格参数-江西核威环保科技有限公司 | 智能门锁电机_智能门锁离合器_智能门锁电机厂家-温州劲力智能科技有限公司 | 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 深圳货架厂家_金丽声精品货架_广东金丽声展示设备有限公司官网 | 北京森语科技有限公司-模型制作专家-展览展示-沙盘模型设计制作-多媒体模型软硬件开发-三维地理信息交互沙盘 | elisa试剂盒-PCR试剂盒「上海谷研实业有限公司」 | 玉米深加工机械,玉米加工设备,玉米加工机械等玉米深加工设备制造商-河南成立粮油机械有限公司 | 贵阳用友软件,贵州财务软件,贵阳ERP软件_贵州优智信息技术有限公司 | 不锈钢丸厂家,铝丸,铸钢丸-淄博智源铸造材料有限公司 | 鄂泉泵业官网|(杭州、上海、全国畅销)大流量防汛排涝泵-LW立式排污泵 | 山东限矩型液力偶合器_液力耦合器易熔塞厂家-淄博市汇川源机械厂 | 耐热钢-耐磨钢-山东聚金合金钢铸造有限公司 | 气弹簧定制-气动杆-可控气弹簧-不锈钢阻尼器-工业气弹簧-可调节气弹簧厂家-常州巨腾气弹簧供应商 | VOC检测仪-甲醛检测仪-气体报警器-气体检测仪厂家-深恒安科技有限公司 | 西门子伺服控制器维修-伺服驱动放大器-828D数控机床维修-上海涌迪 | 诸城网站建设-网络推广-网站优化-阿里巴巴托管-诸城恒泰互联 | 实验室装修_实验室设计_实验室规划设计- 上海广建净化工程公司 | 高精度-恒温冷水机-螺杆式冰水机-蒸发冷冷水机-北京蓝海神骏科技有限公司 | 济南画室培训-美术高考培训-山东艺霖艺术培训画室 | 沈阳庭院景观设计_私家花园_别墅庭院设计_阳台楼顶花园设计施工公司-【沈阳现代时园艺景观工程有限公司】 | 广东机电安装工程_中央空调工程_东莞装饰装修-广东粤标建设有限公司 | 纸张环压仪-纸张平滑度仪-杭州纸邦自动化技术有限公司 | 英国公司注册-新加坡公司注册-香港公司开户-离岸公司账户-杭州商标注册-杭州优创企业 | 直流电能表-充电桩电能表-导轨式电能表-智能电能表-浙江科为电气有限公司 | 广州企亚 - 数码直喷、白墨印花、源头厂家、透气无手感方案服务商! |