在使用Volley作為網絡請求框架的時候,遇到過一個問題,就是在自己的框架中發現打印的日志只有請求一次,但在服務端捕捉到的請求卻是發送了2次。
本文參考自 Volley默認請求多次原因解析
1.volley的請求順序
volley的請求主要都是調用BasicNetwork
里面的performRequest
方法獲取服務器的響應。
大致的過程是:
- 添加header參數到request中
- 發送http
- 解析response
- 返回
主要要注意的是:這個請求的過程是循環的,直到得到服務器的響應或者拋出異常。這也就能解釋為什么會在請求明明只發送一次卻在服務端查看的時候是調用了2次的情況。
2.解決方法
volley還有一個方法getRetryPolicy
就是設置請求超時的時間和超時重復請求的次數
@Override
public RetryPolicy getRetryPolicy() {
RetryPolicy retryPolicy = new DefaultRetryPolicy(50 * 1000,0,0f);
return retryPolicy;
}
其中DefaultRetryPolicy
是一個默認的超時設置對象
- 參數一
DEFAULT_TIMEOUT_MS
是超時時間,時間應該設置的稍微大一點 - 參數二
DEFAULT_MAX_RETRIES
,超時后重復請求的次數,如果不希望有2次請求的情況,則設置為0 - 參數三
DEFAULT_BACKOFF_MULT
是backoff因子,對于請求失敗之后的請求,并不會隔相同的時間去請求Server,不會以線性的時間增長去請求,而是一個曲線增長,一次比一次長,如果backoff因子是2,當前超時為3,即下次再請求隔6S。
下面是我自己實現的,對于JSONObjectRequest請求的一個封裝請求
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方法,將返回的數據格式化位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;
}
}
但是針對以上這種寫法,還是會發現存在2次請求的情況。不知道是不是復寫的方法getRetryPolicy
沒有被調用還是怎樣。有知道煩請告知一二。
這里做一點改進。在將請求添加到請求隊列之前,再顯式得設置retryPolicy
這個屬性。即
basicRequest.setRetryPolicy(new DefaultRetryPolicy(50 * 1000,0,0f));
App.getRequestQueue().add(basicRequest);