Android 学习笔记之Volley开源框架解析(一)
PS:看完了LGD的六場比賽...讓人心酸...
?
學習內容:
1.Http請求的過程...
2.Volley的簡單介紹...
?
1.Http請求...
? 這里只是簡單的說一下Http請求的過程...非常的簡單...首先是發送Request..然后服務器在獲取到Request請求后會對其進行相應的處理,然后以Response的形式進行返回,然后分配Response,即誰發送的請求,那么響應就分配給誰...
?
2.Volley簡單介紹...
? 這里只是先簡單的說一下Volley,Volley框架是由Google發布的一款開源框架...這個框架主要是針對網絡請求而包裝生成的開源框架...主要功能是異步的網絡請求和圖片的加載,適用于Android這種請求頻繁而每次請求數據量并不是很大的這一類網絡請求...通過源碼能夠發現Volley有非常好的擴展性,更多的地方采用接口的設計...所以我們都可以自己重寫內部的一些方法...總體的設計思路也是非常的明確的...
? 客戶端如果想通過網絡連接來連接服務器,那么首先需要發送相關請求...每一個請求都需要被建立,那么建立請求的類就靠Request.java來實現...
?
? Request.java(源碼解析)
? 簡單的說說Request.java,這是Volley的最核心的類,Request.java不僅僅封裝了Request請求,還包括對服務器返回的Response的數據信息進行相應的處理..總之Request.java是一個最大的父類,內部封裝了非常多的方法...其他的幾個子類都是通過繼承Request.java從而實現自己的功能...Request只是對外提供了一個接口,任何方式的請求只需要實現接口就能夠實例化自己的請求對象,創建自己內部的方法..從而形成一種良好的擴展...
? 凡是繼承了Request.java必須要實現的一個方法...
abstract protected Response<T> parseNetworkResponse(NetworkResponse response);?? 這個方法是對網絡服務器響應的一個解析過程..也是最后由這個函數通過postResponse方法,將Response傳遞給ResponseDelivery從而對響應進行分發,不難理解,在每一個Request中實現這個方法,那么也就能夠知道是誰發出的請求,這樣在分發響應的時候也就不會產生錯誤...
??2.1 public void addMarker(String tag){}函數...
public void addMarker(String tag) {if (MarkerLog.ENABLED) {mEventLog.add(tag, Thread.currentThread().getId());} else if (mRequestBirthTime == 0) {mRequestBirthTime = SystemClock.elapsedRealtime();}}? addMarker函數,其實是就是一個標志,這個函數可以為每一個request添加相應事件標識符,這樣我們就可以通過捕獲標識符的方式從而對每一個request做進一步的操作.
? 比如說一個網絡請求從請求隊列取出的標識:request.addMarker("network-queue-take");
??????? 一個請求被取消的標識:request.addMarker("network-discard-cancelled");
? 在Volley中很容易看到這些標識,他們的存在就是為了捕獲每一個請求的發生狀態,通過捕獲這些狀態,比如說一個請求已經完成,那么我們捕獲到了請求完成之后,我們就需要將這次請求從請求隊列當中移除,那么這個操作的執行就需要首先捕獲到請求的狀態,我們才能夠采取下一步的操作...總之就是通過標識才能夠清楚的了解請求到底執行到了何種狀態...
?
? 2.2 以下幾個函數完成實體部分(Body)中驗證參數的傳遞以及編碼過程...
? 2.2.1 public byte[] getPostBody() throws AuthFailureError{}
??????? public byte[] getBody() throws AuthFailureError{}
public byte[] getPostBody() throws AuthFailureError {// Note: For compatibility with legacy clients of volley, this implementation must remain// here instead of simply calling the getBody() function because this function must// call getPostParams() and getPostParamsEncoding() since legacy clients would have// overridden these two member functions for POST requests.Map<String, String> postParams = getPostParams();if (postParams != null && postParams.size() > 0) {return encodeParameters(postParams, getPostParamsEncoding());}return null;}public byte[] getBody() throws AuthFailureError {Map<String, String> params = getParams();if (params != null && params.size() > 0) {return encodeParameters(params, getParamsEncoding());}return null;}?? 這兩個函數想必大家看函數名稱估計都能明白到底是怎么回事了,只不過這里有個小小的區別...第一個方法僅僅是對Post請求方式中Body實體部分的獲取,而第二個是對Post或Put請求方式中Body實體部分的獲取...
? 我們知道網絡請求時,信息是以數據報的形式進行傳遞的,數據報有頭部(Headers)和實體(Body)部分...實體一般都是封裝著想要發送的數據以及驗證信息...因此想要獲取Body中的實體數據就必須要通過某種方法來獲取原生態的實體數據(Body)...獲取了實體數據之后,就可以提交驗證以及發送數據...那么上面兩個函數就是用來解決這個問題的...
? 我們可以從源碼看到,二者分別調用getParams()和getPostParams()函數...
? 2.2.2 protected Map<String,String> getPostParams() throws AuthFailureError{}
??????? protected Map<String,String> getParams() throws AuthFailureError{}
?
protected Map<String, String> getPostParams() throws AuthFailureError {return getParams();}protected Map<String, String> getParams() throws AuthFailureError {return null;}? 這兩個方法就是獲取數據報中Body用于驗證或授權時傳遞的參數,通過源碼我們可以看到,方法的返回值是空值,這也不難理解,如果客戶端想要完成驗證和授權,必須要由客戶端發送驗證數據,通過對客戶端驗證數據信息的抓取,接著應用程序重寫上面的兩個方法,客戶端的驗證數據信息被封裝到這兩個方法內,這樣服務器就可以真正的獲取到客戶端提交的信息了..來張圖片方便大家理解...
? 這里還涉及到了一個參數的編碼...通過調用encodeParamters()方法...
? 2.2.3 private byte[] encodeParameters(Map<String,String>params,String paramsEncoding){}
? 這個方法需要對傳遞過來的所有參數進行遍歷...將參數轉化成 postid=4868291&update=1 這樣的形式...我們在訪問網站的時候經常會在url看到這樣類似的字串,那也就是傳遞的參數想必也就不難理解了...
?
private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {StringBuilder encodedParams = new StringBuilder();try {for (Map.Entry<String, String> entry : params.entrySet()) {encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));encodedParams.append('=');encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));encodedParams.append('&');}return encodedParams.toString().getBytes(paramsEncoding);} catch (UnsupportedEncodingException uee) {throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);}}?
? 2.3 請求完成后需要執行的函數...
? 2.3.1 void finish(final String tag){}
? 當一個請求完成之后需要對做出一些操作,首先需要做的事情就是將請求隊列中的這次請求進行移除操作,因為請求已經完成...這也不難理解,也就是下面源碼第一個if執行的過程,他會再次調用RequestQueue中finish()函數,來移除這次請求,這個源碼就先不介紹...等到后面介紹RequestQueue源碼的時候再細細說一下...我們只需要知道現在它的功能就行了...也是這個函數的主要部分...而下面第二個if()函數,其實是為了轉儲這次請求中所有的日志文件,為了以后的調試...
void finish(final String tag) {if (mRequestQueue != null) {mRequestQueue.finish(this);}if (MarkerLog.ENABLED) {final long threadId = Thread.currentThread().getId();if (Looper.myLooper() != Looper.getMainLooper()) {// If we finish marking off of the main thread, we need to// actually do it on the main thread to ensure correct ordering.Handler mainThread = new Handler(Looper.getMainLooper());mainThread.post(new Runnable() {@Overridepublic void run() {mEventLog.add(tag, threadId);mEventLog.finish(this.toString());}});return;}mEventLog.add(tag, threadId);mEventLog.finish(this.toString());} else {long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {VolleyLog.d("%d ms: %s", requestTime, this.toString());}}}?
? 2.4 Request的構造函數...
? 2.4.1 public Request(String url,Response.ErrorListener listener){}
??????? public Request(int method,String url,Response.ErrorListener listener){}
? 構造函數分為兩種,一個是直接通過url來執行請求,一個是通過指定提交方式,然后通過url來執行請求...
public Request(String url, Response.ErrorListener listener) {this(Method.DEPRECATED_GET_OR_POST, url, listener);}public Request(int method, String url, Response.ErrorListener listener) {mMethod = method;mUrl = url;mErrorListener = listener;setRetryPolicy(new DefaultRetryPolicy());mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();}? Request只是一個抽象接口,為外部暴露接口,從而讓其他的類去實現,其中還有許多的方法,包括請求失敗時的重試策略,以及請求緩存的一些定義...還有許多變量和方法,只是在Request中進行了封裝,而真正去調用和實現這些方法則需要其他的類進行擴展...因此Request的源碼只是做一些簡單的介紹..介紹的也是其中非常重要的方法...其他的內容則在后續進行介紹...
?
?
?????
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/RGogoing/p/4868291.html
總結
以上是生活随笔為你收集整理的Android 学习笔记之Volley开源框架解析(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转:C#使用Log4Net记录日志
- 下一篇: 解决三星 BIOS 模式没有 Fast