Volley源碼分析

volley中的所有請求都是抽象類Request的具體實現(xiàn)類

public abstract class Request?implements Comparable<Request<T>>{ ?

// 實現(xiàn)Comparable接口的意義是在于當(dāng)請求隊列中的數(shù)量較多時,就需要按優(yōu)先級或者是先進(jìn)先出的方式依次發(fā)送請求

? ? private static finalStringDEFAULT_PARAMS_ENCODING="UTF-8"; ?// Put和Post的請求參數(shù)的默認(rèn)編碼

}

Volley支持的請求用接口定義以下九個常量過時的DEPRECATED_GET_OR_POST,Get,Post,Put,Delete,Head,Options,Trace,Patch

public interface Method{

? int DEPRECATED_GET_OR_POST= -1; ?// 過時的Get或者Post請求

? int GET=0;

? int POST=1;

? int PUT=2;

? int DELETE=3;

? int HEAD=4;

? int OPTIONS=5;

? int TRACE=6;

? int PATCH=7;

}

Request中有幾個重要的final修飾的成員變量

private finalStringmUrl; ?// 請求的Url地址

private finalResponse.ErrorListenermErrorListener; ?// 錯誤監(jiān)聽器

private RequestQueue mRequestQueue; // 與該請求相關(guān)的請求隊列

private boolean mShouldCache=true; // 這次請求是否應(yīng)該被緩存下來

private boolean mCanceled=false; // 該請求的狀態(tài)是否變成已取消

private boolean mResponseDelivered=false; // 該請求的響應(yīng)是否已經(jīng)被分發(fā)出去

private boolean mShouldRetryServerErrors=false; // 該服務(wù)器的錯誤是否應(yīng)該被再次審核

private Cache.Entry mCacheEntry=null; // 從緩存中取出的請求必須要保證已經(jīng)在網(wǎng)絡(luò)中刷新過,并且緩存的對象需要用該變量存下來,為了防止發(fā)生響應(yīng)沒有被修改,換句話說也就是確保最新的響應(yīng)

Request的構(gòu)造函數(shù)

public Request(String url,Response.ErrorListener listener) { ?// 已經(jīng)過時的構(gòu)造方法

? ? this(Method.DEPRECATED_GET_OR_POST,url,listener);

}

public Request(int method,String url,Response.ErrorListener listener) { //?

? ? mMethod=method;

? ? mUrl=url;

? ? mErrorListener=listener;

? ? setRetryPolicy(newDefaultRetryPolicy()); // 設(shè)置默認(rèn)的重試策略

? ? mDefaultTrafficStatsTag=findDefaultTrafficStatsTag(url);

}

Request中重要的方法 終止該請求(將請求從隊列中移除)

void finish(final String tag) {

? if(mRequestQueue!=null) {

? ? ? ?mRequestQueue.finish(this); ?// 隊列將該請求移除出去

? ?}

if(MarkerLog.ENABLED) {

? ? final longthreadId=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(newRunnable() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void run() {

? ? ? ? ? ? ? ?mEventLog.add(tag,threadId);?

? ? ? ? ? ? ? ?mEventLog.finish(this.toString());?

? ? ? ? ? }

? ? ? });

? ? ?return;

? ? }

? ? ?mEventLog.add(tag,threadId);

? ? mEventLog.finish(this.toString());

? ?}

?}

將參數(shù)寫成字節(jié)碼

publicStringgetBodyContentType() {

? ? return"application/x-www-form-urlencoded; charset="+getParamsEncoding();

}


public byte[] getBody() throwsAuthFailureError{

? ? Map?params=getParams();

? ? if(params!=null&?ms.size()>0) {

? ? ? ? ?return encodeParameters(params,getParamsEncoding());

? ? }

? ? return null;

? }

將參數(shù)編碼拼接在URL中

private byte[]encodeParameters(Mapparams,StringparamsEncoding) {

? ?StringBuilderencodedParams=newStringBuilder();

? try{

? ?for(Map.Entryentry: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(UnsupportedEncodingExceptionuee) {

? ? ? ?throw newRuntimeException("Encoding not supported: "+paramsEncoding,uee);

? }

}

Request的子類可以重寫該方法,可以針對跟精確的錯誤類型做相應(yīng)的處理

protected VolleyError parseNetworkError(VolleyError volleyError) {

? return ?volleyError;

}

子類必須重寫該方法去解析原生的響應(yīng)結(jié)果,返回一個恰當(dāng)?shù)捻憫?yīng)結(jié)果

abstract protected Response<T> ?parseNetworkResponse(NetworkResponseresponse);

子類必須實現(xiàn)該方法,分發(fā)解析過后的響應(yīng)給那些監(jiān)聽回調(diào),這個響應(yīng)的參數(shù)必須保證不為空,響應(yīng)解析失敗將不會支持分發(fā)操作

abstract protected void deliverResponse(T response);

分發(fā)錯誤給ErrorListener監(jiān)聽回調(diào)

public voiddeliverError(VolleyErrorerror) {

? ?if(mErrorListener!=null) {

? ? ? mErrorListener.onErrorResponse(error);

? ? }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Volley源碼分析之流程和緩存 前言 Android一開始提供了HttpURLConnection和HttpCl...
    大寫ls閱讀 636評論 0 6
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • 我的博客: Volley 源碼分析 Volley 的使用流程分析 官網(wǎng)示例 創(chuàng)建一個請求隊列 RequestQue...
    realxz閱讀 2,054評論 1 11
  • 前言 本文是一篇日常學(xué)習(xí)總結(jié)性的文章,筆者通過分析經(jīng)典網(wǎng)絡(luò)框架Volley的源碼,望以鞏固Android網(wǎng)絡(luò)框架中...
    Armstrong_Q閱讀 585評論 0 7
  • 1. 功能介紹 1.1. Volley Volley 是 Google 推出的 Android 異步網(wǎng)絡(luò)請求框架和...
    愛碼士平頭哥閱讀 1,844評論 0 9