Volley網(wǎng)絡(luò)框架
由來(lái)
volley 是 Goole I/O 2013上發(fā)布的網(wǎng)絡(luò)通信庫(kù)厌处,使網(wǎng)絡(luò)通信更快戈泼、更簡(jiǎn)單绷柒、更健壯。 數(shù)據(jù)不大但通信頻繁
Volley //內(nèi)部封裝了HttpURLConnection和HttpClient
使用場(chǎng)景
網(wǎng)絡(luò)通信更快乐埠、更簡(jiǎn)單、更健壯。 適用于數(shù)據(jù)不大但通信頻繁的場(chǎng)景茅特,不適合大文件下載。
注意事項(xiàng):一般整個(gè)App只使用一個(gè)請(qǐng)求隊(duì)列RequestQueue//定義一個(gè)類繼承Application進(jìn)行初始化,注意清單加name
功能
Json棋枕,圖像等異步下載
網(wǎng)絡(luò)請(qǐng)求的排序(scheduling)
網(wǎng)絡(luò)請(qǐng)求的優(yōu)先級(jí)處理
緩存
多級(jí)別取消請(qǐng)求
和 Activity 的生命周期聯(lián)動(dòng)(Activity 結(jié)束時(shí)同時(shí)取消所有網(wǎng)絡(luò)請(qǐng)求)
更具體請(qǐng)參考http://www.reibang.com/p/ec3dc92df581
Build.VERSION.SDK_INT獲取手機(jī)版本號(hào)
谷歌在高版本當(dāng)中已經(jīng)去掉了httpClient白修,所以這里必須做版本號(hào)的判斷。
版本號(hào)大于等于9就使得HttpStack對(duì)象的實(shí)例為HurlStack(使用了HttpURLConnection)重斑,如果小于9則實(shí)例為HttpClientStack(使用了HttpClient)兵睛。
Volley的簡(jiǎn)單使用
注意事項(xiàng):一般整個(gè)App只使用一個(gè)請(qǐng)求隊(duì)列RequestQueue//定義一個(gè)類繼承Application進(jìn)行初始化,注意清單加name
代碼使用
//[1]請(qǐng)求隊(duì)列的對(duì)象
RequestQueue mQueue = Volley.newRequestQueue(context);
//[2]創(chuàng)建JsonObjectRequest對(duì)象(抽象類,多態(tài))用來(lái)請(qǐng)求 JSON 數(shù)據(jù)
//JsonObjectRequest,StringRequset等
JsonObjectRequest request = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
//參數(shù)2請(qǐng)求體requestBody,用Json數(shù)據(jù)請(qǐng)求服務(wù)器
@Override
public void onResponse(JSONObject jsonObject) {
// TODO
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
// TODO
}
});
//[3]請(qǐng)求對(duì)象加入 mQueue 的隊(duì)列中
mQueue.add(request);
//Volley圖片控件NetworkImageView
mNetworkImageView.setImageUrl(url,imageLoader);//參數(shù)2:緩存對(duì)象
Volley源碼分析
緩存操作流程圖.png
[1]創(chuàng)建RequestQueue對(duì)象
RequestQueue queue = Volley.newRequestQueue(context);
調(diào)用newRequestQueue(context,httpStack)
RequestQueue newRequestQueue(context,httpStack){
發(fā)起網(wǎng)絡(luò)請(qǐng)求.//HttpStack//NetWork//線程池,4個(gè)線程N(yùn)etWorkDispatcher
初始化磁盤緩存:創(chuàng)建磁盤緩存對(duì)象DiskBasedcache
分發(fā)器Delivery分發(fā),//TODO,綁定Handler,綁定主線程Looper//Looper.getMainLooper()作用:線程切換
RequestQueue的start(){
開(kāi)啟1線程mCacheDispatcher.start();//開(kāi)啟線程自動(dòng)run()//mCacheDispatcher.run()
開(kāi)啟4線程 networkDispatcher.start();//開(kāi)啟線程自動(dòng)run()//mCacheDispatcher.run().run()
}
return queue;
}
//可以優(yōu)化的地方(Volley的缺點(diǎn)),線程池(4個(gè)NetworkDispatcher)沒(méi)有管理,只是簡(jiǎn)單的一個(gè)數(shù)組,一旦線程池掛了,就訪問(wèn)不了網(wǎng)絡(luò)了.
[2]請(qǐng)求隊(duì)列添加請(qǐng)求//queue.add(request)
不用排隊(duì)mCurrentRequests: 添加到當(dāng)前請(qǐng)求mCurrentRequests.add(request);
要排隊(duì)mWaitingRequests: 添加到請(qǐng)求隊(duì)列mCacheQueue.add(request)
沒(méi)有請(qǐng)求:請(qǐng)求到網(wǎng)絡(luò)隊(duì)列mNetworkQueue.add(request);
[3]CacheDispatcher.start()線程開(kāi)啟觸發(fā)CacheDispatcher的run()
設(shè)置線程優(yōu)先級(jí)Process.setThreadPriority
while(true){
拿到請(qǐng)求mCacheQueue.take();
請(qǐng)求判斷是否可用:
request.isCanceled()
獲取緩存:
Cache.Entry entry = mCache.get(request.getCacheKey());
緩存判斷:
有緩存:
//讀取數(shù)據(jù):Cache.Entry
//解析和返回結(jié)果response: request.parseNetworkResponse
沒(méi)有緩存or過(guò)期: 無(wú)緩存entry == null//過(guò)期entry.isExpired()
mNetworkQueue.put(request);
有緩存但是否需要刷新: //if(!entry.refreshNeeded())
否:通過(guò)分發(fā)器分發(fā)mDelivery.postResponse(request, response);
是:通過(guò)分發(fā)并重新請(qǐng)求
mDelivery.postResponse(request, response, new Runnable() {
@Override
public void run() {
mNetworkQueue.put(request);
}
}
}
[4]networkDispatcher.start()線程開(kāi)啟觸發(fā)NetWorkDispatcher的run()
設(shè)置線程優(yōu)先級(jí)Process.setThreadPriority()
while (true) {
拿到請(qǐng)求mQueue.take();
執(zhí)行網(wǎng)絡(luò)請(qǐng)求NetworkResponse networkResponse = mNetwork.performRequest(request);
解析和返回結(jié)果response: request.parseNetworkResponse(networkResponse);
當(dāng)網(wǎng)絡(luò)可用并且有數(shù)據(jù)就緩存
if (request.shouldCache() && response.cacheEntry != null) {
mCache.put(request.getCacheKey(), response.cacheEntry);
request.addMarker("network-cache-written");
}
通過(guò)分發(fā)器分發(fā): mDelivery.postResponse(request, response);
緩存調(diào)度和網(wǎng)絡(luò)調(diào)度.png
}