【问题标题】:HttpResponse.getEntity() NetworkOnMainThreadException [duplicate]HttpResponse.getEntity() NetworkOnMainThreadException [重复]
【发布时间】:2012-11-08 04:26:51
【问题描述】:

可能重复:
NetworkOnMainThreadException

很长一段时间以来,我一直在使用在AsyncTask 中执行http 请求的通用代码。 AsyncTask 返回一个 HttpResponse 对象。一切运行良好,GUI 线程从未冻结或发生任何事情。

现在,突然之间,这创建了一个NetworkOnMainThreadException

serverResponse.getEntity().getContent();

什么鬼??为什么getEntity() 被认为是网络?在我看来,该行仅将响应转换为输入流,不需要网络连接。谁做出了这个决定?为什么他们决定这应该是网络?

异步任务:

public class AsyncHttpTask extends AsyncTask<HttpRequestInfo, Integer, HttpRequestInfo> {

public AsyncHttpTask() {
    super();
}

protected HttpRequestInfo doInBackground(HttpRequestInfo... params) {
    HttpRequestInfo rinfo = params[0];
    try{
        HttpClient client = new DefaultHttpClient();
        HttpResponse resp = client.execute(rinfo.getRequest());
        rinfo.setResponse(resp);
    }
    catch (Exception e) {
        rinfo.setException(e);
    }
    return rinfo;
}

@Override
protected void onPostExecute(HttpRequestInfo rinfo) {
    super.onPostExecute(rinfo);
    rinfo.requestFinished();
}   

回调接口:

    public interface HttpCallback {

        public void onResponse(HttpResponse serverResponse);
        public void onError(Exception e);

    }

HttpRequestInfo:

public class HttpRequestInfo {

    private HttpUriRequest request_;
    private HttpCallback callback_;
    private Exception exception_;
    private HttpResponse response_;

    public HttpRequestInfo(HttpUriRequest request, HttpCallback callback) {
        super();
        request_ = request;
        callback_ = callback;
    }

    public HttpUriRequest getRequest() {
        return request_;
    }

    public void setRequest(HttpUriRequest request) {
        request_ = request;
    }

    public HttpCallback getCallback() {
        return callback_;
    }

    public void setCallback(HttpCallback callback) {
        callback_ = callback;
    }

    public Exception getException() {
        return exception_;
    }

    public void setException(Exception exception) {
        exception_ = exception;
    }

    public HttpResponse getResponse() {
        return response_;
    }

    public void setResponse(HttpResponse response) {
        response_ = response;
    }

    public void requestFinished(){
        if(exception_ != null){
            callback_.onError(exception_);
        }
        else {
            callback_.onResponse(response_);
        }
    }
}

然后我使用 jackson 将 json 响应转换为对象。这就是发生异常的地方:

@Override
public <T> T handleResponse(HttpResponse serverResponse, Class<T> typeOfResponse) {
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    T responseObject = null;
    try {
        responseObject = mapper.readValue(serverResponse.getEntity().getContent(),typeOfResponse); //THIS LINE IS EVIL
    } catch (JsonParseException e) {
        throw new ARException("Couldn't handle the response because the http response contained malformed json.",e);
    } catch (JsonMappingException e) {
        throw new ARException("Mapping the json response to the response object " + typeOfResponse + " failed.",e);
    } catch (IllegalStateException e) {
        throw new ARException("Couldn't convert the http response to an inputstream because of illegal state.",e);
    } catch (IOException e) {
        throw new ARException("Couldn't convert the http response to an inputstream.",e);
    }
    return responseObject;
}

【问题讨论】:

  • 我阅读了那个问题和博文。不同之处在于,我在异步任务中进行网络连接。我得到一个 HttpResponse 回来。只有当我调用 HttpResponse.getEntity() 时才会发生异常。

标签: android networkonmainthread


【解决方案1】:

因为您必须在单独的线程而不是主线程中使用网络。您可以使用AsyncTaskThread + Handler。如果您使用的是 AsyncTask,则所有工作都与网络一起工作,您必须在 doInBackground 部分执行。

【讨论】:

  • httpResponse.getEntity().getContent() 是否被视为网络?为什么?
  • 我发布了我的所有代码。我不是在异步任务中完成所有网络吗?
  • httpResponse.getEntity().getContent() 适用于网络,因为您从 HttpResponse 获取数据。你在哪里执行handleResponse?
  • 我在主线程中调用handleResponse。但是这个对象叫做http RESPONSE。我认为 HttpResponse 是网络后返回的响应。所有 httpResponse.getEntity().getContent() 所做的就是将响应转换为输入流。那不应该是网络!! :)
  • 如果我使用新线程或异步任务,它绝对有效。我想我真正的问题是,为什么这被认为是网络?如果我知道这被认为是网络,我永远不会这样做!
猜你喜欢
  • 2011-07-06
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
相关资源
最近更新 更多