Retrofit2源码解析03-OkHttpCall.enqueue

来源:互联网 发布:wifi速度测试软件 编辑:程序博客网 时间:2024/05/22 15:07

接下来我们来分析下OkHttpCall.enqueue,OkHttpCall也是继承自Retrofit的call,并在内部调用OkHttp3.Call.enqueue。

public void enqueue(final Callback<T> callback) {    //...    call.enqueue(new okhttp3.Callback() {      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)          throws IOException {        Response<T> response;        try {          response = parseResponse(rawResponse);        } catch (Throwable e) {          callFailure(e);          return;        }        callSuccess(response);      }      @Override public void onFailure(okhttp3.Call call, IOException e) {        try {          callback.onFailure(OkHttpCall.this, e);        } catch (Throwable t) {          t.printStackTrace();        }      }      private void callFailure(Throwable e) {        try {          callback.onFailure(OkHttpCall.this, e);        } catch (Throwable t) {          t.printStackTrace();        }      }      private void callSuccess(Response<T> response) {        try {          callback.onResponse(OkHttpCall.this, response);        } catch (Throwable t) {          t.printStackTrace();        }      }    });}

主要来看parseResponse,这里会根据不同的状态码,来做不同的操作。

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {    ResponseBody rawBody = rawResponse.body();    // Remove the body's source (the only stateful object) so we can pass the response along.    rawResponse = rawResponse.newBuilder()        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))        .build();    int code = rawResponse.code();    if (code < 200 || code >= 300) {      try {        // Buffer the entire body to avoid future I/O.        ResponseBody bufferedBody = Utils.buffer(rawBody);        return Response.error(bufferedBody, rawResponse);      } finally {        rawBody.close();      }    }    if (code == 204 || code == 205) {      return Response.success(null, rawResponse);    }    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);    try {      T body = serviceMethod.toResponse(catchingBody);      return Response.success(body, rawResponse);    } catch (RuntimeException e) {      // If the underlying source threw an exception, propagate that rather than indicating it was      // a runtime exception.      catchingBody.throwIfCaught();      throw e;    }}  

如果一切顺利,会调用serviceMethod.toResponse,在这里,会调用responseConverter的convert方法。
这里的responseConverter就是Retrofit Build创建过程中,
以GsonConverterFactory为例,代码如下。

T toResponse(ResponseBody body) throws IOException {    return responseConverter.convert(body);}final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {    private final Gson gson;    private final TypeAdapter<T> adapter;    GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {        this.gson = gson;        this.adapter = adapter;    }    @Override public T convert(ResponseBody value) throws IOException {    JsonReader jsonReader = gson.newJsonReader(value.charStream());    try {      return adapter.read(jsonReader);    } finally {      value.close();    }}}  

总结

OkHttpCall.enqueue就是回去调用OkHttp,当成功回调时,会调用responseConverter的convert方法,进行数据类型的转换,比如GsonResponseBoyConverter,就会把ResponseBody中的流转换为JsonReader,在转化为相应的对象类型。

其他

文中Retrofit的源码是Retrofit2.1.0

原创粉丝点击