2012-04-03 3 views
2

У меня есть установки, где я выполнять мои запросы HTTP в doInBackground() методы в AsyncTask следующим образом:Может ли EntityUtils.toString() вызвать исключение NetworkOnMainThreadException?

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

Этого HttpResponse объект затем передается на onPostExecute() метод моего AsyncTask быть передан обработчиком (первоначальный абонент запроса HTTP) и обрабатывали, как это необходимо, следующим образом:

  • проверки кода ответа с использованием httpResponse.getStatusLine().getStatusCode();
  • получение ответа с использованием EntityUtils.toString(httpResponse.getEntity())).

Эта установка отлично работает на телефонах, работающих под управлением старых версий Android.

Запуск моего приложения теперь на сэндвиче с мороженым (Galaxy Nexus) Я обнаружил, что первые несколько HTTP-запросов в моем приложении, как и выше, работают нормально, но затем есть один HTTP-запрос, который последовательно генерирует исключение со стеком следа следующим образом (немного обрезана для удобства чтения):

....

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

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

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

...

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

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

android.os.NetworkOnMainThreadException

Я смущен. Означает ли это, что метод EntityUtils.toString(HttpEntity) является потенциальным виновником броска нового (и так раздражающего) NetworkOnMainThreadException? Если да, то какие-либо рекомендации по переработке моей установки, чтобы сделать HTTP-запросы в отдельном потоке, чтобы ответ мог обрабатываться в основном потоке?

+0

У меня эта же проблема, но это происходит только на некоторых телефонах и только на некоторых запросах .. Иногда EntityUtils.toString работает отлично .. странно –

+0

Также остерегайтесь кодовая страница по умолчанию 'EntityUtils.toString': HTTP://stackoverflow.com/questions/30642237/what-exactly-returns-entityutils-tostringresponse/43611274#43611274 –

ответ

5

Попробуйте следующее: измените функцию doInBackground, чтобы вернуть значение ответа HTTP.

protected String doInBackground(HttpRequestBase... httpRequests) 
{ 
    HttpResponse httpResponse = HttpClient.execute(HttpUriRequest); 
    if (httpResponse.getEntity() != null) { 
     return EntityUtils.toString(httpResponse.getEntity()); 
    } 
    return ""; 
} 
+0

Это дает мне только сообщение сообщения ответа. Мне также нужна строка состояния (т. Е. «HttpResponse.getStatusLine()») и потенциально локаль ответа (т. Е. «HttpResponse.getLocale()»). Я предполагаю, что мне придется извлечь все эти свойства в методе 'AsynTask.doInBackground()', как вы предлагаете, и затем обернуть их в свой собственный класс ServerResponse, который будет передан методу 'onPostExecute()' ... если нет лучшего пути ?! –

+0

Да. Вы должны сделать это таким образом. – Blehi

+0

Вы уверены, что должны сделать это вот так? Почему эти методы будут делать сети? – Adam