retrofit源码二

前言

今天继续探寻retrofit源码,(上一节)看到了[https://www.jianshu.com/p/3290df7d1e71]的OkHttpCall的enqueue方法。我们知道,retrofit使用时要这样才能正式开始网络请求

......
service.fetchNextTitle().enqueue(object : Callback {
       override fun onResponse(call: Call< TitleModel >, response: Response) {
           TODO("Not yet implemented")
       }

       override fun onFailure(call: Call, t: Throwable) {
           TODO("Not yet implemented")
       }
   })

这个enqueue方法就是调用的OkHttpCall的enqueue,那让我们看看源码把~

OkHttpCall的enqueue

@Override
  public void enqueue(final Callback callback) {
    okhttp3.Call call;
    synchronized (this) {
         ......//这里省略的代码是call的赋值
    if (canceled) {
      call.cancel();
    }
    call.enqueue(//1
        new okhttp3.Callback() {
          @Override
          public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            Response response;
            try {
              response = parseResponse(rawResponse);//2
            } catch (Throwable e) {
              throwIfFatal(e);
              callFailure(e);
              return;
            }

            try {
              callback.onResponse(OkHttpCall.this, response);
            } catch (Throwable t) {
              throwIfFatal(t);
            }
          }

          @Override
          public void onFailure(okhttp3.Call call, IOException e) {
            callFailure(e);
          }

          private void callFailure(Throwable e) {
            try {
              callback.onFailure(OkHttpCall.this, e);
            } catch (Throwable t) {
              throwIfFatal(t);
            }
          }
        });
  }

注释1处调用了okhttp3.call的enqueue方法执行网络请求,注释2处解析响应结果,下面具体看下parseResponse方法具体是如何解析的

Response parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();
    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) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }
    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
      T body = responseConverter.convert(catchingBody);//1
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      catchingBody.throwIfCaught();
      throw e;
    }
  }

根据不同的code码进行不同的操作,如果顺利会调用注释1处的代码,这里的responseConverter就是之前讲的从converterFactories中获取的Converter,在上一节中我们传入的是GsonConverterFactory,因此可以查看GsonConverterFactory的代码。

  @Override
  public Converter responseBodyConverter(
      Type type, Annotation[] annotations, Retrofit retrofit) {
    TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

因此调用的convert方法就是GsonResponseBodyConverter对象的convert方法了,我们来看下这个方法

  @Override
  public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      T result = adapter.read(jsonReader);
      if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
        throw new JsonIOException("JSON document was not fully consumed.");
      }
      return result;
    } finally {
      value.close();
    }
  }

可以看出这个方法主要是使用gson将数据转为需要的格式。
总结出Call的enqueue方法主要做的就是用OKHttp来请求网络并将返回的Response进行数据转换并回调给UI线程。
这里细化一下converterFactories的具体理解:
数据解析器Converter,将response通过converterFactory转换成对应的JavaBean数据形式,常见解析器有GsonConverterFactory、FastJsonConverterFactory,当然也有xml的。

后记

基本完结了,还剩一个callAdapterFactory需要具体讲解一下,下一节见o( ̄︶ ̄)o

你可能感兴趣的:(retrofit源码二)