retrofit 源码解读

引子

retrofit最核心的地方是对okhttp进行封装。实际上完成网络请求的还是okhttp,那么我们看retrofit的源码看的是啥,我觉得主要还是看它是如何利用一系列的设计模式来完成对okhttp的封装。

另外,本文主要沿着2条线索去解读源码,一是看json解析那块,也就是Converter线索,另一个是看请求回调部分,也就是CallAdapter线索。

由于本人水平有限,请各位大佬不吝赐教,错误的地方请直接指出。

废话就说这么多,下面以一段最常用的来代码开始本文的分析。

以下是Retrofit的一般代码流程:


    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client)//指定okHttpClient
            .addConverterFactory(ScalarsConverterFactory.create())//返回对象支持
            .addConverterFactory(GsonConverterFactory.create())//增加返回值为Gson的支持(返回实体类)
            .build();

    final RequestApi postApi = retrofit.create(RequestApi.class);

    Call<AreaUserInfoBean> getcommunityCall = postApi.getAreaUser("getcommunity", "1");

    getcommunityCall.enqueue(new Callback<AreaUserInfoBean>() {

        @Override
        public void onResponse(Call<AreaUserInfoBean> call, Response<AreaUserInfoBean> response) {
            Log.d(TAG, response.body() == null ? "null" : response.body().toString());
            PublicUtils.isMainThread();
        }

        @Override
        public void onFailure(Call<AreaUserInfoBean> call, Throwable t) {
            Log.d(TAG, "失败" + t.toString());
            PublicUtils.isMainThread();
        }

    });

思维图


1.create方法,动态代理模式,利用JDK1.5提供的Proxy类创建对象(同时对对象进行处理),不清楚的可以去了解下。(动态代理参考)
2.3.泛型返回interface接口类,这是我们定义请求的业务URL类,该类只需要定义好参数即可,具体的请求逻辑retrofit帮我们做了,也就是invoke方法内部的逻辑,也是动态代理一种体现。
4.5.6.他调用serviceMehtod.callAdapter.adapte(okhttpCall)来返回一个Call对象,这个Call是retrofit的Call,它是对OkHttp的Call的一个封装,调它的enquene相当于是调okhttp的enquene。然而在adapt内部也对对象进行了一个处理,回调监听啥的。

源码解析

Convertor线索

Retrofit#create()


  public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();//1

          @Override public Object invoke(Object proxy, Method method, Object... args)
              throws Throwable {

            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {//2 
              return method.invoke(this, args);
            }

            if (platform.isDefaultMethod(method)) {//3 
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }

            ServiceMethod serviceMethod = loadServiceMethod(method);//4
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);//5
            return serviceMethod.callAdapter.adapt(okHttpCall);//6
          }
        });
  }

1.platform是retrofit在初始化的时候的一个跨平台参数,这里不深究。
2.如果方法是Object继承下来的方法则直接调用(Method#getDeclareClass()测试报告)。
3.若是平台相关的默认方法也直接调用,这里它默认是false,一般不用考虑。
4.5.6核心逻辑。我们接着往下看。

Retrofit#loadServiceMethod()


  ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);//1
      if (result == null) {//2
        result = new ServiceMethod.Builder(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

1.从缓存里取个ServiceMethod
2.若缓存里没有取到,则去创建
3.返回这个ServiceMethod

那么问题来了,这个ServiceMethod是个啥?

Adapts an invocation of an interface method into an HTTP call.
将接口方法的调用适配为HTTP调用

1.这是ServiceMethod.java类第一行注释。那么我大致可以猜到,它的意思就是将retrofit的call转成okhttp的call。
2.它内部还有2个方法,toResponsetoRequest,这俩个方法可以理解为是将serviceMethod接收的参数转化为真正的请求和响应。

这个暂时先到这里,我们先回到主流程。

    ......

         OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);//5

    return serviceMethod.callAdapter.adapt(okHttpCall);//6

OkHttpCall

全貌:

这个类有这么一窝子方法,其中相对重要的方法是enqueue,excute,parseResponse,cancel

我们记下来分析这几个方法。

OkHttpCall#enquene()


  @Override public void enqueue(final Callback<T> callback) {
    ......

    okhttp3.Call call;
    ......

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = rawCall;
      ......
      if (call == null && failure == null) {
        try {
          call = rawCall = createRawCall();
        } catch (Throwable t) {
              ......
        }
      }
    }

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }

    //重点1.
    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();
        }
      }
    });
  }

其实这段代码我们可以解读为:


 @Override public void enqueue(final Callback<T> callback) {

    okhttp3.Call call = rawCall = createRawCall();

    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) {
          ......
        }
        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();
        }
      }
    });
  }

核心流程就是如此。createRawCall就是创建一个okHttpCall,这里说白了就是retrofit的Call去调okhttp的Call,如果成功,则调用response = parseResponse(rawResponse);,它这个是将rawResonse转换为retrofit的Response。接下来我们看这个方法。

OkHttpCall#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);//1
      return Response.success(body, rawResponse);//1.
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }

目前为止,这个地方总算是和我们分析的第一条线索converter沾点边了,解析数据,但是和我预期的不一致,并没看见converter的身影。但是真的是这样吗?在注释1处点进去看看。

ServiceMethod#toResponse()


  /** Builds a method return value from an HTTP response body. */
  T toResponse(ResponseBody body) throws IOException {
    return responseConverter.convert(body);
  }

看这个变量的定义:

  private final Converter<ResponseBody, T> responseConverter;

看到了一个抽象类Converter,距离我们的目标近了。我们接下来看看它的初始化。

ServiceMethod#ServiceMethod()

  ServiceMethod(Builder<T> builder) {
    ......
    this.responseConverter = builder.responseConverter;
    ......
  }

它可以是在构建ServiceMethod的时候传递进来的。

ServiceMethod#build()


    public ServiceMethod build() {
      callAdapter = createCallAdapter();
      ......
      responseConverter = createResponseConverter();
      ......
    }

也可以是在build()内创建。

ServiceMethod#createResponseConverter()


    private Converter<ResponseBody, T> createResponseConverter() {
      ......
      try {
        return retrofit.responseBodyConverter(responseType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        ......
      }
    }

这里注意了,关键点来了,调用并返回retrofit.responseBodyConverter。
这个retrofit对象就是我们之前构建的retrofit对象。然后我们点进这个方法去看看。

Retrofit#responseBodyConverter()


  public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
  }

Retrofit#nextResponseBodyConverter()


  public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
      Type type, Annotation[] annotations) {

    ......

    int start = converterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        //noinspection unchecked
        return (Converter<ResponseBody, T>) converter;
      }
    }

    ......

  }

这个converterFactories是啥?我们来看我们一开始构建retrofit时的代码


    Retrofit retrofit = new Retrofit.Builder()
            ......
            .addConverterFactory(GsonConverterFactory.create())//增加返回值为Gson的支持(返回实体类)
            .build();

    ↓

    /** Add converter factory for serialization and deserialization of objects. */
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

没错,这里就是我们一开始构建的retroift时候传递进来的GsonConverterFactory.create()被加入到了converterFactories。清除这一点之后,我还有一个疑问,这个converter究竟是怎么解析数据的呢?

不用想,肯定是在请求成功的时候吧。我先猜想它是在成功的时候操作这个集合converterFactories内的converter来解析数据,下面我直接去看请求成功时的代码。

OkHttpCall#onRespaonse

这里我先说下整体回调的流程:

ExecutorCallbackCall.enqueue -> OkHttpCall.enqueue

这里ExecutorCallbackCall看不明白也不要紧,下边讲CallAdapter线索的时候会分析,但是这里只需要记住最终回调到的地方是OkHttpCall的onRespaonse里边。

那么接下来我们看OkHttpCall的onRespaonse方法。


   @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);
      }

这里调用了parseResponse()。再点进去看这个parseResponse方法。


 Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    ......

    try {
      T body = serviceMethod.toResponse(catchingBody);
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      ......
      throw e;
    }
  }

看到调了serviceMethod的toResponse方法。再点进去看这个ServiceMethod的toResponse方法。


  /** Builds a method return value from an HTTP response body. */
  T toResponse(ResponseBody body) throws IOException {
    return responseConverter.convert(body);
  }

我们看到是调用了responseConverter的convert方法。

但是有的朋友可能还有疑问,我们设置的不是一个GsonConvertFactory吗?不是这个GsonResponseBodyConverter呀。那么这里我就简单列一下。

Retrofit#nextResponseBodyConverter - > responseBodyConverter()


  public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
      Type type, Annotation[] annotations) {
    ......
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        //noinspection unchecked
        return (Converter<ResponseBody, T>) converter;
      }
    }

    ......
    throw new IllegalArgumentException(builder.toString());
  }

GsonConverterFactory#responseBodyConverter
可以看到实际上是New了一个GsonResponseBodyConverter


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

因此我们就可以看到如下代码:


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();
    }
  }
}

Converter的线索告一段落,我们回到主流程上,继续分析CallAdapter的线索。

callAdapter线索



    ......

    return serviceMethod.callAdapter.adapt(okHttpCall);

serviceMethod.callAdapter.adapt(okHttpCall)

serviceMethod.callAdapter,那么我们就去看ServiceMethod这个类的方法。

ServiceMethod#build()


 public ServiceMethod build() {
      callAdapter = createCallAdapter();
      ......

      return new ServiceMethod<>(this);
    }

第一行就是createCallAdapter(),点进去看看。

ServiceMethod#createCallAdapter()


 private CallAdapter<?> createCallAdapter() {
      ......
      try {
        return retrofit.callAdapter(returnType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        .......
      }
    }

Retrofit#callAdapter()

  public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

Retrofit#nextCallAdapter()

 public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {

    ......

    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);//这里
      if (adapter != null) {
        return adapter;
      }
    }

    ......

    throw new IllegalArgumentException(builder.toString());
  }

注意这里很重要,先留个坑。我们最后会绕到这边回来。

Retrofit#nextCallAdapter()

nextCallAdapter {

  ......

  for (int i = start, count = adapterFactories.size(); i < count; i++) {
      CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
  }

  ......

}

又是一个集合adapterFactories内去get,ok我们来看retrofit的build方法

Retrfit#build


   public Retrofit build() {
      ......

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();//1
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      ......
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));//2
      ......

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }

Bingo!找到了,原来我们在构建Retrfit也默认创建了一个callAdapter,它是通过platform.defaultCallAdapterFactory(callbackExecutor)来实现的,那么它的真身究竟是什么呢?还记得一开始我们遇见了一个platForm跨平台参数吗。我们这里默认只看Android。

Android#defaultCallAdapterFactory()


static class Android extends Platform {

    //1
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    //2
    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }

}

1.先是拿到一个MainThreadExecutor。
2.再通过这个MainThreadExecutor参数来创建一个工厂。返回给retrofit。

ok,到这里停一停,还记得我们之前留了个坑么?
也就是在Retrofit#nextCallAdapter()那调用了factory的get方法.

ExecutorCallAdapterFactory#get()


 @Override
  public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public <R> Call<R> adapt(Call<R> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

然后再回顾之前我们留的坑。

 public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {

    ......

    CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);//这里

    ......

    throw new IllegalArgumentException(builder.toString());
  }

到这里我们算是把callAdapter赋值赋上了。

然后在这里打住,我们再回到主流程。去看ExecutorCallAdapterFactory的adapt方法。

......

serviceMethod.callAdapter.adapt(okHttpCall)

ExecutorCallAdapterFactory$ExecutorCallbackCall


static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override public void enqueue(final Callback<T> callback) {
      if (callback == null) throw new NullPointerException("callback == null");

      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              if (delegate.isCanceled()) {
                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
              } else {
                callback.onResponse(ExecutorCallbackCall.this, response);
              }
            }
          });
        }

        @Override public void onFailure(Call<T> call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    ......
  }

到这里就是真正的对okhttp的调用了。
1.delegate.enqueue(),这个delegate我们之前分析过,他实际上是OKhttpCall,在OkHttpCall内部是去调用的Okhttp的enqueue。
2.callbackExecutor.execut方法内部直接是调用的一个handler.post(runnable),异步去进行回调。

这也就是我们一开始代码可以这么写的原因。


    getcommunityCall.enqueue(new Callback<AreaUserInfoBean>() {

        @Override
        public void onResponse(Call<AreaUserInfoBean> call, Response<AreaUserInfoBean> response) {
            Log.d(TAG, response.body() == null ? "null" : response.body().toString());
            PublicUtils.isMainThread();
        }

        @Override
        public void onFailure(Call<AreaUserInfoBean> call, Throwable t) {
            Log.d(TAG, "失败" + t.toString());
            PublicUtils.isMainThread();
        }

    });

Thanks

刘望舒:http://liuwangshu.cn/application/network/11-retrofit2-sourcecode.html
拆OkHttp:https://blog.piasy.com/2016/07/11/Understand-OkHttp/
短而精:https://blog.csdn.net/u011692041/article/details/53055763
比较用心的一篇:https://www.jianshu.com/p/0c055ad46b6c

猜你喜欢

转载自blog.csdn.net/user11223344abc/article/details/80858731