【问题标题】:Okhttp showing leaked warning while using with volleyOkhttp 在与 volley 一起使用时显示泄漏警告
【发布时间】:2018-04-29 19:28:29
【问题描述】:

在开发我的 android 应用程序时,我在 Logcat 中收到此警告

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

我使用 Okhttps 作为 volley 的传输层进行网络调用。

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);
    }

}

用于创建请求队列

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

我这样调用url

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));

}

从 Okhttp 问题跟踪器中,我读到我们必须每次都关闭响应主体以避免泄漏,但我不知道在使用 volley 和 Okhttp 时如何做到这一点。

依赖:

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'

【问题讨论】:

标签: android memory-leaks android-volley okhttp okhttp3


【解决方案1】:

在 Kotlin 中我们可以这样使用:

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
                }

【讨论】:

    【解决方案2】:

    我猜你没有在这里显示完整的代码,这条消息是新调用未关闭的结果。

    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;
    

    【讨论】:

    • 我明白你说要使用 close() 方法,但是在上面的代码中,如何在 finally() 块中访问 body.close() ?因为它的局部变量在 try 块中声明!!!
    猜你喜欢
    • 2016-11-17
    • 1970-01-01
    • 2015-03-13
    • 2011-10-23
    • 1970-01-01
    • 2017-01-12
    • 2015-11-24
    • 1970-01-01
    相关资源
    最近更新 更多