【问题标题】:Can EntityUtils.toString() cause a NetworkOnMainThreadException?EntityUtils.toString() 会导致 NetworkOnMainThreadException 吗?
【发布时间】:2012-04-17 07:25:57
【问题描述】:

我有一个设置,我在AsyncTaskdoInBackground() 方法中执行我的http 请求,如下所示:

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

这个HttpResponse 对象随后被传递给我的AsyncTaskonPostExecute() 方法,以传递给处理程序(http 请求的原始调用者)并根据需要进行处理,如下所示:

  • 使用httpResponse.getStatusLine().getStatusCode()检查响应码;
  • 使用EntityUtils.toString(httpResponse.getEntity())获取响应内容。

此设置在运行旧版 Android 的手机上运行良好。

现在在 Ice Cream Sandwich (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 请求以便可以在主线程上处理响应的任何建议?

【问题讨论】:

  • 我也有同样的问题,但它只发生在某些手机上,而且只发生在某些请求上。有时 EntityUtils.toString 工作正常。很奇怪
  • 还要注意EntityUtils.toString的默认字符集:stackoverflow.com/questions/30642237/…

标签: android android-networking android-compatibility


【解决方案1】:

请尝试以下操作:修改您的 doInBackground 函数以返回 HTTP 响应的值。

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

【讨论】:

  • 这只给了我响应的消息实体。我还需要状态行(即HttpResponse.getStatusLine())以及响应的区域设置(即HttpResponse.getLocale())。我想我必须像您建议的那样在AsynTask.doInBackground() 方法中提取所有这些属性,然后将它们包装在我自己的ServerResponse 类中以传递给onPostExecute() 方法......除非有更好的方法? !
  • 是的。你必须这样做。
  • 你确定一定要这样吗?为什么那些方法会做网络???
  • 当实体内容被消费(例如转换为字符串)时,它正在从网络缓冲区读取字节。我个人喜欢使用 ResponseHandler 并返回一个结果对象,但请注意 Android 正在远离 Apache HttpClient(请参阅android-developers.blogspot.com/2011/09/…)。
猜你喜欢
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多