Volley中listener導致的記憶體洩露

王世暉發表於2016-04-26

專案中用Volley作為http框架,封裝了一個JsonRequest,效能優化的時候,LeakCanary一直提示Volley的listener記憶體洩露,檢查了很久也沒發現哪裡出現記憶體洩露

public class JsonRequestImpl extends JsonRequest<JSONObject > {
    public JsonRequestImpl(int method, String url,
                           JSONObject jsonRequest,
                           Response.Listener<JSONObject> listener,
                           Response.ErrorListener errorListener) {
        super(  method,
                url,
                (jsonRequest == null) ? null : jsonRequest.toString(),
                listener,
                errorListener);
    }

    public JsonRequestImpl(String url,
                           JSONObject jsonRequest,
                           Response.Listener<JSONObject> listener,
                           Response.ErrorListener errorListener) {
        this(  jsonRequest == null ? Request.Method.GET : Request.Method.POST,
                url,
                jsonRequest,
                listener,
                errorListener);
    }

    /**
     * @param response
     * @return
     */
    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString =
                    new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    /**
     * 設定超時
     * @return
     */
    @Override
    public RetryPolicy getRetryPolicy() {//設定超時
        RetryPolicy retryPolicy= new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        return retryPolicy;
    }

    /**
     * 設定header
     * @return
     * @throws AuthFailureError
     */
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {//新增header
        Map<String,String> map=new HashMap<String,String>();
        map.put("Accept", "application/json");
        map.put("Content-Type", "application/json; charset=UTF-8");
        return map;
    }
}
獲取Volley請求佇列的時候

requestQueue = Volley.newRequestQueue(context.getApplicationContext());
並沒有直接傳進Activity例項進來,而是使用全域性唯一的context上下文。

傳送請求的時候加TAG,介面離開前臺的時候直接在onPause裡邊取消標記為TAG的網路請求。

還是找不到記憶體洩露的原因,網上查了下資料,說是Volley自己的一個小bug

原來使用的Volley版本是:

compile 'eu.the4thfloor.volley:com.android.volley:2015.01.06'
改為
compile 'com.mcxiaoke.volley:library:1.0.19'

後果然就不再提示記憶體洩露的問題了

unofficial mirror (with some minor bugfix) for volley.

點選開啟連結


相關文章