10

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?

Mark Pazon
  • 6,167
  • 2
  • 34
  • 50
  • I had the same problem but it was isolated to the Android **Emulator**. When trying on a real device, it did not show these issues. Not saying that will helps others, but I tried everything to fix the issue on the Emulator and then I just tried on a real device, and it wasn't an issue. The Emulator was running Android 6 and the real device was on Android 9, btw. – Joshua Pinter Aug 21 '19 at 19:20
  • Coming back here to reply to my own comment. We eventually did see this on the real device as well, but only under circumstances where a bunch of a download URLs were not valid and not returning actual content. So something is for sure still leaking and causing too many open files. – Joshua Pinter Oct 03 '19 at 15:16

4 Answers4

15

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".

Mark Pazon
  • 6,167
  • 2
  • 34
  • 50
1

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();
}
Swapnil Kale
  • 2,620
  • 2
  • 23
  • 21
  • 1
    Thanks for your answer. I am already doing this but still doesnt fix the issue on devices running Jellybean. – Mark Pazon Dec 04 '13 at 07:21
0

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

user207421
  • 305,947
  • 44
  • 307
  • 483
0

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.

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245