使用byteStream

时间:2016-03-18 22:02:33

标签: java android okhttp3 connection-leaks

我在Logcat消息中不断收到连接泄露警告,即使我已经关闭了我发出的每个请求的每一个主体。

我有两个GET和POST请求的包装器方法,它们启动请求并传回响应。

protected Response getRequest(String url, OkHttpClient client) throws IOException, SMUserLoggedOutException {
    // Create the builder.
    Request.Builder getRequestBuilder = new Request.Builder();

    // Set URL.
    getRequestBuilder.url(url);

    // Set Headers.
    setHeaders(getRequestBuilder, REQUEST_TYPE_GET);

    // Build the request.
    Request getRequest = getRequestBuilder.build();

    // Fire
    Response getResponse = client.newCall(getRequest).execute();

    // Check for logout.
    if (checkForLogout(getResponse) && !mIgnoreLoggedOutExceptions) {
        // Close body.
        getResponse.body().close();

        // Throw logged out exception.
        throw new SMUserLoggedOutException("User logged out");
    }

    // Return the response.
    return getResponse;
}

protected Response postRequest(String url, RequestBody formBody, OkHttpClient client) throws IOException, SMUserLoggedOutException {
    // Create the builder.
    Request.Builder postRequestBuilder = new Request.Builder();

    // Set URL.
    postRequestBuilder.url(url);

    // Set Headers.
    setHeaders(postRequestBuilder, REQUEST_TYPE_POST);

    // Set POST body.
    postRequestBuilder.post(formBody);

    // Build the request.
    Request postRequest = postRequestBuilder.build();

    // Fire.
    Response postResponse = client.newCall(postRequest).execute();

    // Check for logout.
    if (checkForLogout(postResponse) && !mIgnoreLoggedOutExceptions) {
        // Close response body.
        postResponse.body().close();

        // Throw logged out exception.
        throw new SMUserLoggedOutException("User logged out");
    }

    // Return the response.
    return postResponse;
}

我有第三种方法,通过响应InputStream来阅读body().byteStream()来处理将响应正文转换为字符串。

protected String getResponseBodyAsString(Response response) throws IOException {
    // Reference the input stream.
    InputStream inputStream;

    String contentEncodingHeader = response.header(HEADER_CONTENT_ENCODING);
    if (contentEncodingHeader != null && contentEncodingHeader.equals(STRING_GZIP)) {
        // Read the zipped contents.
        inputStream = new GZIPInputStream(response.body().byteStream());
    } else {
        // Read the normal contents.
        inputStream = response.body().byteStream();
    }

    // Create and return buffered reader.
    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

    // Read stream.
    StringBuilder sb = new StringBuilder("");
    String line;
    while ((line = br.readLine()) != null) {
        sb.append(line.trim());
    }

    // Close everything.
    response.body().close();

    // I realize this isn't needed, but I kept getting warnings so
    // I figured, what the hell.
    inputStream.close(); 
    br.close();

    // Return the string.
    return sb.toString();
}

我调用的每个getRequest()postRequest()后跟getResponseBodyAsString()方法,如果用户在请求之间注销,则主体也会关闭。然而,我仍然得到连接泄露的警告..

如果您需要任何其他代码,请不要犹豫。

提前致谢。

修改

另一段代码,dunno if会有所帮助。调用getRequest()postRequest()的每个对象都封装在一个捕获任何异常的ASyncTask对象中。

try {
    // Execute the main task.
    success = mTransferObjectBase.run();
} catch (Exception e) {
    // Save exception.
    mException = e;

    // Cancel the task.
    cancel(true);
}

现在,没有关闭这些响应的body(),但是,在我看到泄漏警告的零情况下,ASyncTask被取消了。所以没有任何例外可以阻止它被关闭。

EDIT2

阅读此post后,我意识到如果您手动添加“Accept-Encoding ... gzip”标头,GZIP将无法透明处理。删除手动添加确实可以透明地解码,但是,我只在响应正文中获得了一行文档。

GZIP透明处理

  

< td align =“center”>< img width =“208”height =“110”src =“images / alert_loginlogo.gif”/>< / td

这就是我回来的全部内容。如果我自己处理流解码,我会毫无问题地获得整个文档。

这可能是图书馆的一个错误,我在这里不知所措。

0 个答案:

没有答案