標籤:
這文章是用來記錄自己最近使用volley的StringRequest的一些心得,以及volley關於request的代碼深讀。
從網路上可以知道,volley適合資料量不大但是通訊頻繁的情境。volley提供的便利功能有如下這些:
- JSON,映像等的非同步下載;
- 網路請求的排序(scheduling)
- 網路請求的優先順序處理
- 緩衝
- 多層級取消請求
- 和Activity和生命週期的聯動(Activity結束時同時取消所有網路請求)
從一些網路前輩和自己使用的情況來說,volley的圖片處理並不是最佳,我選擇了Picasso,所以我只用到了request,以及和Activity生命週期的聯動兩個特性。
之前寫了一篇volley的初接觸,主要是Volley.newRequestQueue(getApplicationContext());這句代碼的解讀。
以下開始解讀StringRequest。
網路上的前輩都把StringRequest請求當做自訂請求,和JsonObjecy JsonArray 區別開,我也不清楚為什麼要這樣區別,暫且沒用過volley的json請求,但是看過介紹,感覺所有的request都差不多。
使用情景,利用StringRequest請求解析一段xml資料。
StringRequest request = new StringRequest( Request.Method.GET, Contants.HTTP_SERVER + Contants.HTTP_TABS, new Response.Listener<String>(){
@Override
public void onResponse(String response){
//這裡處理請求返回的response
... ...
}
}, new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError error){
//這裡處理請求失敗的工作
LogUtils.d(TAG,error.toString());
}
}
);
還是一句代碼,所有用到的參數都出現了,現在到StringRequest看看情況
public class StringRequest extends Request<String> { private final Listener<String> mListener; public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) { super(method, url, errorListener); //這裡是調用super 不是 this mListener = listener; } public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) { this(Method.GET, url, listener, errorListener); } @Override protected void deliverResponse(String response) { mListener.onResponse(response); //設定我們的listener } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) {
//字面意思 解析網路響應 String parsed; try { parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); } catch (UnsupportedEncodingException e) { parsed = new String(response.data); } return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); }
StringRequest類的代碼不多,但都是重要的組成部分。
這裡記錄自己當初的兩個惑點super(method, url, errorListener) 和 parseNetworkResponse & mListener.onResponse(response)的區別。
首先是super(method, url, errorListener) :StringRequest繼承Request<String>,跳轉到Request<String>中
public Request(int method, String url, Response.ErrorListener listener) { mMethod = method; mUrl = url; mErrorListener = listener; setRetryPolicy(new DefaultRetryPolicy()); mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url); }
Request中儲存了提交方式,串連的url,錯誤監聽介面,並設定了重試策略,而且從url中找到通訊狀態標誌(有什麼用?)
設定重試策略感覺很好理解,看看DefaultRetryPolicy類就知道七八分了,作用大概就是設定url串連的失敗重試的一些屬性(我自己腦補的-_-!!!)
public DefaultRetryPolicy() { this(DEFAULT_TIMEOUT_MS, DEFAULT_MAX_RETRIES, DEFAULT_BACKOFF_MULT); } ... /** * Constructs a new retry policy. * @param initialTimeoutMs The initial timeout for the policy. * @param maxNumRetries The maximum number of retries. * @param backoffMultiplier Backoff multiplier for the policy. */ public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) { mCurrentTimeoutMs = initialTimeoutMs; mMaxNumRetries = maxNumRetries; mBackoffMultiplier = backoffMultiplier; }
剩下的mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url);函數的javadoc裡解釋返回The hashcode of the URL‘s host component, or 0 if there is none,這下就不太好腦補了,還是先看看函數的實現。
private static int findDefaultTrafficStatsTag(String url) { if (!TextUtils.isEmpty(url)) { Uri uri = Uri.parse(url); if (uri != null) { String host = uri.getHost(); if (host != null) { return host.hashCode(); } } } return 0; }
看到出奇簡單的代碼,我聯想到了volley的緩衝機制,聽說是簡單的判斷url是否相同,難道就是這個??是不是這個也不重要了,反正StringRequest的初始化屬性如上。
剩下就是deliverResponse和parseNetworkResponse,然後從網路上找到了一篇說得比較清楚得文章
http://www.apihome.cn/view-detail-70213.html
我用自己的白話文歸納一下:parseNetworkResponse是用於特定類型(String、Json、JsonArray、Image)請求的解析,把服務端返回的資料解析成指定類型,然後系統回調deliverResponse派發相應的執行個體當中。不太明白可以看看以上類型對應的Request,裡面都用parseNetworkResponse把NetworkResponse轉變成相應類型。
Note:在我沒寫這篇文章前,我都是直接在初始化StringRequest請求的時候,我都沒有重寫parseNetworkResponse,直接拿到服務端的原始string,然後在Response.listener中的onResponse中進行處理,感覺不太native。感謝網路上的前輩,感謝自己。
Android.Volley的解讀:request