在使用Volley作為網(wǎng)絡(luò)請(qǐng)求框架的時(shí)候,遇到過一個(gè)問題,就是在自己的框架中發(fā)現(xiàn)打印的日志只有請(qǐng)求一次拌阴,但在服務(wù)端捕捉到的請(qǐng)求卻是發(fā)送了2次。
本文參考自 Volley默認(rèn)請(qǐng)求多次原因解析
1.volley的請(qǐng)求順序
volley的請(qǐng)求主要都是調(diào)用BasicNetwork
里面的performRequest
方法獲取服務(wù)器的響應(yīng)的烁。
大致的過程是:
- 添加header參數(shù)到request中
- 發(fā)送http
- 解析response
- 返回
主要要注意的是:這個(gè)請(qǐng)求的過程是循環(huán)的褐耳,直到得到服務(wù)器的響應(yīng)或者拋出異常。這也就能解釋為什么會(huì)在請(qǐng)求明明只發(fā)送一次卻在服務(wù)端查看的時(shí)候是調(diào)用了2次的情況渴庆。
2.解決方法
volley還有一個(gè)方法getRetryPolicy
就是設(shè)置請(qǐng)求超時(shí)的時(shí)間和超時(shí)重復(fù)請(qǐng)求的次數(shù)
@Override
public RetryPolicy getRetryPolicy() {
RetryPolicy retryPolicy = new DefaultRetryPolicy(50 * 1000,0,0f);
return retryPolicy;
}
其中DefaultRetryPolicy
是一個(gè)默認(rèn)的超時(shí)設(shè)置對(duì)象
- 參數(shù)一
DEFAULT_TIMEOUT_MS
是超時(shí)時(shí)間铃芦,時(shí)間應(yīng)該設(shè)置的稍微大一點(diǎn) - 參數(shù)二
DEFAULT_MAX_RETRIES
,超時(shí)后重復(fù)請(qǐng)求的次數(shù)襟雷,如果不希望有2次請(qǐng)求的情況刃滓,則設(shè)置為0 - 參數(shù)三
DEFAULT_BACKOFF_MULT
是backoff因子,對(duì)于請(qǐng)求失敗之后的請(qǐng)求耸弄,并不會(huì)隔相同的時(shí)間去請(qǐng)求Server咧虎,不會(huì)以線性的時(shí)間增長(zhǎng)去請(qǐng)求,而是一個(gè)曲線增長(zhǎng)计呈,一次比一次長(zhǎng)砰诵,如果backoff因子是2征唬,當(dāng)前超時(shí)為3,即下次再請(qǐng)求隔6S茁彭。
下面是我自己實(shí)現(xiàn)的总寒,對(duì)于JSONObjectRequest請(qǐng)求的一個(gè)封裝請(qǐng)求
public class BasicRequest extends JsonObjectRequest{
public BasicAPI basicAPI;
public BasicRequest(BasicAPI basicAPI,Response.Listener<JSONObject> successListener,
Response.ErrorListener errorListener ){
super(basicAPI.getHttpType(), basicAPI.getUrl(),null, successListener, errorListener);
LogUtils.e("[url]"+basicAPI.getUrl());
this.basicAPI = basicAPI;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return basicAPI.getHeaders();
}
@Override
public byte[] getBody() {
return basicAPI.getBody();
}
/**
* 重寫parseNetworkResponse方法,將返回的數(shù)據(jù)格式化位UTF-8
*
* @param response
* @return
*/
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String je = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
String temp = new String(response.data, basicAPI.getParamsEncoding());
return Response.success(new JSONObject(temp), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException var3) {
return Response.error(new ParseError(var3));
} catch (JSONException var4) {
return Response.error(new ParseError(var4));
}
}
@Override
public String getBodyContentType() {
if (StringUtils.isNoEmpty(basicAPI.getDiyBodyContentType())) {
return basicAPI.getDiyBodyContentType();
}
return super.getBodyContentType();
}
@Override
public RetryPolicy getRetryPolicy() {
RetryPolicy retryPolicy = new DefaultRetryPolicy(50 * 1000,0,0f);
return retryPolicy;
}
}
但是針對(duì)以上這種寫法理肺,還是會(huì)發(fā)現(xiàn)存在2次請(qǐng)求的情況摄闸。不知道是不是復(fù)寫的方法getRetryPolicy
沒有被調(diào)用還是怎樣。有知道煩請(qǐng)告知一二妹萨。
這里做一點(diǎn)改進(jìn)年枕。在將請(qǐng)求添加到請(qǐng)求隊(duì)列之前,再顯式得設(shè)置retryPolicy
這個(gè)屬性眠副。即
basicRequest.setRetryPolicy(new DefaultRetryPolicy(50 * 1000,0,0f));
App.getRequestQueue().add(basicRequest);