Volley之發送多次網絡請求

在使用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);
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容