Okhttp showing leaked warning while using with volley
Asked Answered
F

2

6

While developing my android application I'm getting this warning in my Logcat

WARNING: A connection to https://... was leaked. Did you forget to close a response body?

I'm using Okhttps as a transport layer for the volley for network calling.

class OkHttpStack extends HurlStack {

private final OkUrlFactory okUrlFactory;

    OkHttpStack() {
       this(new OkUrlFactory(new OkHttpClient()));
    }

    private OkHttpStack(OkUrlFactory okUrlFactory) {
        if (okUrlFactory == null) {
            throw new NullPointerException("Client must not be null.");
        }
        this.okUrlFactory = okUrlFactory;
    }

    @Override
    protected HttpURLConnection createConnection(URL url) throws 
    IOException {
        return okUrlFactory.open(url);
    }

}

For creating requestQueue

synchronized RequestQueue getRequestQueue() {
    if (mRequestQueue == null) {
        mRequestQueue = Volley.newRequestQueue(mContext,new OkHttpStack());
    }
    return mRequestQueue;
}
<T> void addToRequestQueue(Request<T> req) {
    getRequestQueue().add(req);
}

I'm calling url like this

public void postCall(final String Url, JSONObject Data, final ResponseCallback responseCallback){

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(mUrl+Url, Data,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.d(TAG,response.toString());
                    responseCallback.onGettingResponse(response);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d(TAG,error.toString());
                    responseCallback.onError(error);
                }
            });
    jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
            TIMEOUT_IN_SECONDS,
            0,
            0));

    mRestApiCall.getInstance(mContext).addToRequestQueue(jsonObjectRequest.setTag(mRequestTag));

}

From Okhttp issues tracker, I read that We have to close the response body each time to avoid leak but I don't get it how to do this while using volley and Okhttp.

Dependencies :

compile 'com.android.volley:volley:1.0.0'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
Fennec answered 16/11, 2017 at 9:59 Comment(2)
#47025525Chellean
Please remove the http logging which is one of the reason for this issueBiblical
W
2

you are not showing the complete code here i guess, this message is result of new call not being closed.

private String get(final String url) {
String res = null;
ResponseBody body;
try {
    final Request req = new Request.Builder().url(url).get().build();
    final Response resp = ok.newCall(req).execute();
    final int code = resp.code();
    if (code == 200) {
        body = resp.body();
        res = body.string();
    }
}
catch (final Throwable th) {
    System.out.println(th.getMessage());
  }
finally() {
    if(body != null)
      body.close(); // this would be missing somewhere in your code where you are receiving your response
}
return res;
Willie answered 21/11, 2017 at 13:16 Comment(1)
i understand you are saying to use close() method, but in above code, how body.close() is accessible in finally() block ? because its local variable declared in try block !!!Adjudge
G
2

in Kotlin we can use this way:

try {
                val req: Request = Request.Builder().url(url).get().build()
                val client = OkHttpClient()
                val resp: Response = client.newCall(req).execute()
                val code: Int = resp.code() // can be any value
                body= resp.body()
                if (code == 200) {
                    body?.close() // I close it explicitly
                }
Glabrate answered 16/3, 2021 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.