2

I have a setup where I perform my http requests in the doInBackground() method of an AsyncTask as follows:

@Override
protected HttpResponse doInBackground(HttpRequestBase... httpRequests)
{
    HttpResponse httpResponse = HttpClient.execute(HttpUriRequest);
    return httpResponse;
}

This HttpResponse object is then passed on to the onPostExecute() method of my AsyncTask to be passed on to a handler (the original caller of the http request) and processed as necessary, as follows:

  • checking the response code using httpResponse.getStatusLine().getStatusCode();
  • getting the response content using EntityUtils.toString(httpResponse.getEntity())).

This setup has been working fine on phones running older versions of Android.

Running my app now on Ice Cream Sandwich (Galaxy Nexus) I find that the first few http requests in my app as above work fine but then there is this one http request which consistently throws an exception with a stack trace as follows (trimmed slightly for readability):

....

at org.apache.http.util.EntityUtils.toString(EntityUtils.java:139)

at java.io.InputStreamReader.close(InputStreamReader.java:145)

at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:213)

...

at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:151)

at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084)

android.os.NetworkOnMainThreadException

I am confused. Does this then mean that the EntityUtils.toString(HttpEntity) method is a potential culprit for throwing the new (and ever so annoying) NetworkOnMainThreadException? If so, any advice on reworking my setup to make http requests in a separate thread such that the response can be processed on the main thread?

Community
  • 1
  • 1
Adil Hussain
  • 30,049
  • 21
  • 112
  • 147
  • I have this same problem but it only happens on some phones and only on some requests.. Sometimes EntityUtils.toString works fine.. weird – Matt Wolfe Sep 10 '12 at 23:19
  • Also beware the default charset of `EntityUtils.toString`: http://stackoverflow.com/questions/30642237/what-exactly-returns-entityutils-tostringresponse/43611274#43611274 – Christophe Roussy Apr 25 '17 at 12:58

1 Answers1

5

Please try the following: modify your doInBackground function to return the value of the HTTP response.

protected String doInBackground(HttpRequestBase... httpRequests)
{
    HttpResponse httpResponse = HttpClient.execute(HttpUriRequest);
    if (httpResponse.getEntity() != null) {
      return EntityUtils.toString(httpResponse.getEntity());
    }
    return "";
}
Blehi
  • 1,990
  • 1
  • 18
  • 20
  • That only gives me the message entity of the response. I also need the status line (i.e. `HttpResponse.getStatusLine()`) and potentially the locale of the response too (i.e. `HttpResponse.getLocale()`). I guess I'll have to extract all these properties in the `AsynTask.doInBackground()` method like you suggest and then wrap them in my own `ServerResponse` class to be passed on to the `onPostExecute()` method... unless there's a better way?! – Adil Hussain Apr 03 '12 at 16:18
  • Yes. You have to do it in that way. – Blehi Apr 03 '12 at 20:34
  • Are you sure you have to do it like this? Why would those methods be doing networking??? – Adam Nov 20 '12 at 06:01
  • 2
    When the Entity content is consumed (e.g. converted to a string), it is reading bytes from a network buffer. Personally I like to use ResponseHandler and return a result object, but be aware that Android's moving away from the Apache HttpClient (see http://android-developers.blogspot.com/2011/09/androids-http-clients.html). – Sofi Software LLC Feb 11 '13 at 18:45