Mark Pazon
Mark Pazon

Reputation: 6205

Android - HttpUrlConnection is not closing. Eventually results to SocketException

I am encountering some problems with the HttpUrlConnection in devices running Jellybean (4.1 - 4.3) wherein connections are not closed and results to a SocketException "Too many open files" after executing a number of times.

I do call HttpUrlConnection.disconnect() and am closing all the Inputstream, Outputstream, Reader and Writers in a finally block.

Going to adb shell and executing a netstat shows all the connections created by the application are left in CLOSE_WAIT state.

InputStream inputStream = httpUrlConnection.getInputStream();

// After calling inputStream.read() then the problem occurs. I think the 
// inputstream doesn't get closed even after calling close in a finally block. 
// The InputStream is a ChunkedInputStream if that helps.

I have tried other devices running on 2.3.3, 4.0.3 and 4.4 and did not encounter this issue.

Is there another way that I can manually close the connections?

Upvotes: 10

Views: 6302

Answers (4)

Joshua Pinter
Joshua Pinter

Reputation: 47481

Try using OkHttp Instead.

Once you get the Maven dependency added, you can do something like the following to download a file:

OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

OutputStream output = null;

try {
  Request request   = new Request.Builder().url( download_url ).build();
  Response response = okHttpClient.newCall( request ).execute();

  if ( !response.isSuccessful() ) {
    throw new FileNotFoundException();
  }

  output = new FileOutputStream( output_path );

  output.write( response.body().bytes() );
}
finally {
  // Ensure streams are closed, even if there's an exception.
  if ( output != null ) output.flush();
  if ( output != null ) output.close();
}

Switching to OkHttp instantly fixed our leaked file descriptor issue so it's worth trying if you're stuck, even at the expense of adding another library dependency.

Upvotes: 0

Mark Pazon
Mark Pazon

Reputation: 6205

I finally found a workaround. It seems that Jellybean is having an issue on "Keep-Alive" connections. I just added Connection=Close to my request header and now all is working. Doing a netstat, I see that the connections are now being closed and I no longer get the SocketException due to "Too many open files".

Upvotes: 15

Swapnil Kale
Swapnil Kale

Reputation: 3040

Check If you have tried all of the below... There might be something missing.. other wise it should not have any problem.

InputStream in;
HttpsURLConnection urlConnection =null;
try {
    URL url = new URL(Url);

    urlConnection = (HttpsURLConnection) url
                     .openConnection();
    //5 Second timeout
    urlConnection.setReadTimeout(5*1000);

    in = urlConnection.getInputStream();
    int responseCode = urlConnection.getResponseCode();

    if (responseCode != HttpURLConnection.HTTP_OK) {
         InputStream errInputStream = urlConnection.getErrorStream();
        //Print error message and response code..
         errInputStream.close();
    }
    in.close();
} catch (Exception e) {
    e.printStackTrace();
} finally{
    if(urlConnection != null)
        urlConnection.disconnect();
}

Upvotes: 1

user207421
user207421

Reputation: 310893

You might be better off not calling disconnect() and thus allowing it to do HTTP connection pooling.

Upvotes: 0

Related Questions