今天就帶大家一層層剝光Volley這位懵懂無知少女(14年出生,應該算無知少女)的外衣,帶大家輕輕撫摸Volley每一寸肌膚,進入Volley的身體,為達到完美效果,開頭錄有激情小視頻,觀看時請自備紙巾,各位現在需要做的就是搬一把椅子,打開電腦,雙擊Android studio導入Volley源碼,隨我一起觀看錄製的激情小視頻帶著大家一起飛,觀看激情小視頻過程中,如能讓你內心微微一顫有所收穫,感受到滿滿的愛意,點讚或打賞都是最美的祝福,橫屏觀看效果更佳。
android面試題-okhttp內核剖析
與源碼相關面試題一
通過一個小慄子慢慢剝開神秘的面紗。
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.baidu.com";StringRequest stringRequest =
new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() { @Override
public void onResponse(String response) { } }, new Response.ErrorListener() { @Override
public void onErrorResponse(VolleyError error) { } }); queue.add(stringRequest);
RequestQueue queue = Volley.newRequestQueue(this);
進入源碼分析:
public static RequestQueue newRequestQueue(Context context) {
return newRequestQueue(context, (HttpStack)null);}
1)該方法有兩個參數,第一個Context是上下文,第二個參數為null
public static RequestQueue newRequestQueue(Context context,
HttpStack stack) { File cacheDir = new File(context.getCacheDir(), "volley");
String userAgent = "volley/0";
try {
String network = context.getPackageName(); PackageInfo queue = context.getPackageManager().getPackageInfo(network, 0); userAgent = network + "/" + queue.versionCode; } catch (NameNotFoundException var6) { } if(stack == null) {
if(VERSION.SDK_INT >= 9) { stack = new HurlStack(); } else { stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } } BasicNetwork network1 = new BasicNetwork((HttpStack)stack); RequestQueue queue1 = new RequestQueue(new DiskBasedCache(cacheDir),
network1); queue1.start();
return queue1; }
1)初始化緩存文件,名字叫volley。
2)獲取到當前應用包名和包的基本信息,並且給userAgent 重新賦值。
3)stack 傳遞過來為null,所以直接走if判斷裡面。
4)在這個if中對版本號進行了判斷,如果版本號大於等於9就使得HttpStack對象的實例為HurlStack,如果小於9則實例為HttpClientStack。至於這裡為何進行版本號判斷,實際代碼中已經說明了,請看下文。
5)BasicNetwork是Network接口的實現,BasicNetwork實現了performRequest方法,其作用是根據傳入的HttpStack對象來處理網絡請求。緊接著new出一個RequestQueue對象,並調用它的start()方法進行啟動,然後將RequestQueue返回。RequestQueue是根目錄下的一個類,其作用是一個請求調度隊列調度程序的線程池。這樣newRequestQueue()的方法就執行結束了。
第四條如何分析出來請看如下代碼:
public class HurlStack implements HttpStack public class HttpClientStack
implements HttpStack
繼承httpStack接口
public interface HttpStack { HttpResponse performRequest(Request<?> var1, Map<String, String> var2) throws IOException, AuthFailureError;}
接口當中有如下方法,performRequest,大家有沒有覺得奇怪都繼承同一個方法,並且都實現一樣的接口同樣的方法,實際上子類實現方法不一樣,代碼如下:
HttpClientStack代碼如下:public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError {HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);
addHeaders(httpRequest, additionalHeaders);
addHeaders(httpRequest, request.getHeaders())this.onPrepareRequest(httpRequest)HttpParams httpParams = httpRequest.getParams()int timeoutMs = request.getTimeoutMs()HttpConnectionParams.setConnectionTimeout(httpParams, 5000)HttpConnectionParams.setSoTimeout(httpParams, timeoutMs)return this.mClient.execute(httpRequest)}
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { . URL parsedUrl1 = new URL(url); HttpURLConnection connection = this.openConnection(parsedUrl1, request); .. return response;}}
由以上得知HttpClientStack走的是httpClient,HurlStack走的是HttpURLConnection ,谷歌在高版本當中已經去掉了httpClient,所以這裡必須做版本號的判斷。
繼續源碼分析,現在再來看下RequestQueue隊列的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(); }}
1)創建了一個CacheDispatcher的實例,然後調用了它的start()方法
2)for循環裡去創建NetworkDispatcher的實例,並分別調用它們的start()方法
3)這裡的CacheDispatcher和NetworkDispatcher都是繼承自Thread的,而默認情況下for循環會執行四次,也就是說當調用了Volley.newRequestQueue(context)之後,就會有五個線程一直在後臺運行,不斷等待網絡請求的到來,其中一個CacheDispatcher是緩存線程,四個NetworkDispatcher是網絡請求線程。
第三條如何分析出來for循環會執行四次 , 請看如下代碼分析:
public RequestQueue(Cache cache, Network network, int threadPoolSize, ResponseDelivery delivery) { . this.mDispatchers = new NetworkDispatcher[threadPoolSize]; . }
threadPoolSize大小是4,如何看出來請看如下代碼:
public RequestQueue(Cache cache, Network network, int threadPoolSize) { this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper()))); }
public RequestQueue(Cache cache, Network network) { this(cache, network, 4); }
通過構造方法傳遞,默認是4,如上已經把第一行代碼分析完畢,進入第二部分。
RequestQueue queue = Volley.newRequestQueue(this);