Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google provides 2 different examples of HttpURLConnection usage - Should we call HttpURLConnection's disconnect, or InputStream's close?

Tags:

android

Google is providing 2 different examples of HttpURLConnection usage.

Calling InputStream's close

http://developer.android.com/training/basics/network-ops/connecting.html

// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string.
private String downloadUrl(String myurl) throws IOException {
    InputStream is = null;
    // Only display the first 500 characters of the retrieved
    // web page content.
    int len = 500;

    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Starts the query
        conn.connect();
        int response = conn.getResponseCode();
        Log.d(DEBUG_TAG, "The response is: " + response);
        is = conn.getInputStream();

        // Convert the InputStream into a string
        String contentAsString = readIt(is, len);
        return contentAsString;

    // Makes sure that the InputStream is closed after the app is
    // finished using it.
    } finally {
        if (is != null) {
            is.close();
        } 
    }
}

Calling HttpURLConnection's disconnect

http://developer.android.com/reference/java/net/HttpURLConnection.html

   URL url = new URL("http://www.android.com/");
   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in);
    finally {
     urlConnection.disconnect();
   }
 }

For resource leakage and performance consideration (Need not to setup network connection from ground up, as my app will communicate with same server most of the time), should we

  1. Call HttpURLConnection's disconnect only.
  2. Call the InputStream's close only.
  3. Call both HttpURLConnection's disconnect & InputStream's close (Haven't seen such official example so far).
like image 428
Cheok Yan Cheng Avatar asked Apr 17 '14 14:04

Cheok Yan Cheng


People also ask

Do I need to disconnect HttpURLConnection?

Yes you need to close the inputstream first and close httpconnection next. As per javadoc. Each HttpURLConnection instance is used to make a single request but the underlying network connection to the HTTP server may be transparently shared by other instances.

How do I close HttpURLConnection?

To close the connection, invoke the close() method on either the InputStream or OutputStream object. Doing that may free the network resources associated with the URLConnection instance.

What is HttpURLConnection?

The Java HttpURLConnection class is http specific URLConnection. It works for HTTP protocol only. By the help of HttpURLConnection class, you can retrieve information of any HTTP URL such as header information, status code, response code etc.

Is HttpURLConnection thread safe?

Is HttpURLConnection thread safe? Each instance of HttpURLConnection may be used for one request/response pair. Instances of this class are not thread safe.


1 Answers

According to Oracle's Java, calling the disconnect() may close the underlying socket connection, if the connection is idle (not fetching anything). This "indicates that other requests to the server are unlikely in the near future" using that same HttpUrlConnection instance. You will have to reopen a new socket connection by creating another HttpUrlConnection.

However, Google has modified HttpUrlConnection so that socket connections can be reused. In Android, the underlying Socket used by a HttpUrlConnection may be persisted and reused for multiple requests. If you call disconnect after completing your request, it may send the socket to a pool containing other idle connections, ready to be reused. The system does this to reduce latency.

From the documentation:

Unlike other Java implementations, this will not necessarily close socket connections that can be reused. You can disable all connection reuse by setting the http.keepAlive system property to false before issuing any HTTP requests.

So you should call disconnect to release resources (streams and sockets), but some of the resources released may be reused (i.e. the socket will go into a pool of idle sockets, ready for the next HttpUrlConnection instance to reuse it).

As for why the first example did not call disconnect(), that is the Java SE way of reusing the connection (I think, it's been a while). What the author did was manually close the InputStream of the connection and left the socket open and idle for reuse. The second example shows the correct way on Android.

In summary: calling disconnect() on Android will close any InputStream or OutputStream used for the connection and may send the socket used for the connection to a pool, ready to be reused for other requests. So, if you call disconnect(), there is no need to call InputStream#close().

like image 197
ugo Avatar answered Oct 12 '22 22:10

ugo