拆轮子系列--Retrofit2源码分析

96
滑板上的老砒霜
2018.08.16 13:27 字数 1109

0.前言

Retrofit是一个基于okhttp的网络请求框架,相当于对于okhttp的一次封装,同理,也是square公司出的,square出品,必属精品,最近有时间,分析仪下它的工作流程,

1.基本使用

  interface TestService
    {

        @GET("/")
        fun test(): Call<String>
    }
    
class ResponseConvertFactory : Converter.Factory()
    {
        override fun responseBodyConverter(type: Type?, annotations: Array<out Annotation>?, retrofit: Retrofit?): Converter<ResponseBody, String>?
        {
            return Converter<ResponseBody, String> {
                it.string()
            }

        }

        override fun stringConverter(type: Type?, annotations: Array<out Annotation>?, retrofit: Retrofit?): Converter<*, String>?
        {
            return super.stringConverter(type, annotations, retrofit)
        }
    }


 val retrofit = Retrofit.Builder().baseUrl("http://www.baidu.com")
                .addConverterFactory(ResponseConvertFactory())
                .build()
        val testService = retrofit.create(TestService::class.java)
        val call = testService.test()
        call.enqueue(object : Callback<String>
        {
            override fun onFailure(call: Call<String>?, t: Throwable?)
            {

            }

            override fun onResponse(call: Call<String>?, response: Response<String>?)
            {
                println("response is ${response?.body()}")
            }

        })    

这是一个简单的异步http get请求,由于只分析流程,由简单的进入就行了,个人认为看代码了解流程和其设计模式才是最重要的,不需要扣的太厉害。

2.Retrofit的创建

Retrofit的创建采用的建造者模式

val retrofit = Retrofit.Builder().baseUrl("http://www.baidu.com")
                .addConverterFactory(ResponseConvertFactory())
                .build()

直接看Retrofit.Builder的build方法

 public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

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

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());

      // Add the built-in converter factory first. This prevents overriding its behavior but also
      // ensures correct behavior when using converters that consume all types.
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);

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

这里传入了一个CallAdapter.Factory的list,里面的数据是Builder里的calladapter.Factory的list,也就是你在addCallAdapterFactory()方法中传入的参数,这里传入的factory会放入builder的calladapter.Factory的list里,然后又放入了一个默认的calladapterfactory,这个factory是platform的参数,而这个platform是在实例化Builder的时候传入的

 private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

如果是跑在android系统,那么返回的就会是Android,看一Android

static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();
      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);
      }
    }
  }

可以看到platform返回的CallAdapterFactory就是ExecutorCallAdapterFactory。关于他的作用稍后再谈。

还有一个Convert.Factory的list,这里是先加入了一个BuiltInConverters,然后放入存在Builder里的Convert.Factory的list,Convert.Factory主要是用来生成Convert来对http请求体和响应报文进行转换。

2.发行请求前的准备

       val testService = retrofit.create(TestService::class.java)
        val call = testService.test()

通过这两个方法,生成了一个实现TestService接口的实例,调用这个接口的方法返回一个Call。接下来就看看这是怎么做的,如何为接口生成了一个实例,还有怎么生成的Call。

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

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.adapt(okHttpCall);
          }
        });
  }

well well,很明显,这是一个动态代理,如果对动态代理不清楚的,可以参考我之前的文章
拆轮子系列--动态代理。通过动态代理实现了一个实现接口的代理类,接下来看InvocationHandler,如果方法不是来自接口而是object的方法,那么就直接调用,如果是来自接口,那么可以看到先生成了一个serviceMethod,看一下loadServiceMethod方法

ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

很简单,如果缓存有,就取出一个ServiceMethod,否则就创建一个ServiceMethod,并添加到缓存,还是建造者模式,看一下ServiceMethod.Builder的build方法

 public ServiceMethod build() {
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();
      if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError("'"
            + Utils.getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
      }
      responseConverter = createResponseConverter();

      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

      if (httpMethod == null) {
        throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      }

      if (!hasBody) {
        if (isMultipart) {
          throw methodError(
              "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
          throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
        }
      }

      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) {
        Type parameterType = parameterTypes[p];
        if (Utils.hasUnresolvableType(parameterType)) {
          throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
              parameterType);
        }

        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        if (parameterAnnotations == null) {
          throw parameterError(p, "No Retrofit annotation found.");
        }

        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }

      if (relativeUrl == null && !gotUrl) {
        throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
      }
      if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError("Non-body HTTP method cannot contain @Body.");
      }
      if (isFormEncoded && !gotField) {
        throw methodError("Form-encoded method must contain at least one @Field.");
      }
      if (isMultipart && !gotPart) {
        throw methodError("Multipart method must contain at least one @Part.");
      }

      return new ServiceMethod<>(this);
    }

先看一下createCallAdapter这个方法

 private CallAdapter<T, R> createCallAdapter() {
      Type returnType = method.getGenericReturnType();
      if (Utils.hasUnresolvableType(returnType)) {
        throw methodError(
            "Method return type must not include a type variable or wildcard: %s", returnType);
      }
      if (returnType == void.class) {
        throw methodError("Service methods cannot return void.");
      }
      Annotation[] annotations = method.getAnnotations();
      try {
        //noinspection unchecked
        return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create call adapter for %s", returnType);
      }
    }

根据method返回值的Type和注解,调用retrofit的callAdapter返回Calladapter,看一下Retrofit的calladapter方法。

public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }
  
  public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

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

    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
        .append(returnType)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }

言简意赅,遍历Retrofit的CallAdapterFactory list,找到符合要求的calladapter就返回,所以还记得calladapterfactory list的顺序吧,默认的calladapterfactory也就是ExecutorCallAdapterFactory是放在最后的,所以如果你在构建Retrofit的时候添加了别的Calladapter,如果符合条件,是会拦截。RxJavaCallAdapterFactory.create()这个眼熟吧,就是因为它最终返回的是Observable而不是Call。其实这个CallAdapter的作用就是讲OkhttpCall转化为其他数据结构,默认的就是将OkhttpCall转换为ExecutorCallbackCall。
再回到build方法

responseConverter = createResponseConverter();

和返回CallAdapter差不多,只不过这是返回的ResponseConvert
接下来

 for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

遍历方法注解得到相应参数,具体就不说了。

然后又生成了一个OkhttpCall

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

你会发现这个OkhttpCall实现了OkHttp的call接口,看它的enque方法

@Override public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "callback == null");

    okhttp3.Call call;
    Throwable failure;

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

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

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

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

    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response<T> response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          callFailure(e);
          return;
        }

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

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

这里就是生成了一个Okhttp的call,然后接着就是okhttp的网络请求流程了,如果okhttp不熟悉可以看我之前的文章拆轮子系列--okhttp3源码分析

重新回到invaoctaionhandler,最后调用了serviceMethod.adapte方法,

T adapt(Call<R> call) {
    return callAdapter.adapt(call);
  }

可以看到就是调用了calladapter的adapt方法,前面说了默认的calladapter是ExecutorCallAdapterFactory制造的

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
  final Executor callbackExecutor;

  ExecutorCallAdapterFactory(Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

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

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

可以看到返回了一个匿名内部类,他的adapt方法实际返回了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) {
      checkNotNull(callback, "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);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response<T> execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call<T> clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }

可以发现这个也实现了Okhttp的call接口,同时还持有了一个callbackexecutor和之前生成的okhttpcall,可以发现调用它的enqueu方法真正执行网络请求的就是okhttpcall,而这个callbackexecutor实际是

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

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

很明显,通过这种方式保证了回调结果在主线程。

(盗张图帮助理解)
图片来自

image

image

关注我的公众号

日记本