4

重複の可能性:
NetworkOnMainThreadException

長い間、私はでhttpリクエストを行うジェネリックコードを使用してきましたAsyncTask。はオブジェクトを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;
}
4

1 に答える 1

2

メインではなく別のスレッドでネットワークを操作する必要があるためです。AsyncTaskまたはThread + Handlerを使用できます。AsyncTaskを使用している場合は、すべてネットワークで動作し、doInBackground部分で実行する必要があります。

于 2012-11-20T06:21:19.987 に答える