Retrofit源码学习

老规矩,从使用的角度深入源码。

一、创建Retrofit对象

Retrofit retrofit = new Retrofit.Builder().baseUrl(url)
                	.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                	.addConverterFactory(GsonConverterFactory.create())
                	.build();
1、new Retrofit.Builder()究竟做了什么?
// Retrofit的静态内部类Builder类
// 看见这种Buidler我们就知道,Retrofit对象的创建必然是基于建造者设计模式去创建的
public static final class Builder {
	// 平台Android/java8
    private final Platform platform;
    // 默认OKHttpClient
    private @Nullable okhttp3.Call.Factory callFactory;
    // url
    private HttpUrl baseUrl;
    // 数据转换器工厂的List,比如上面我们传入的GsonConverterFactory
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    // 网络请求适配器工厂的List,比如上面我们传入的RxJava2CallAdapterFactory
    private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
    // 回调执行
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;

    Builder(Platform platform) {
      this.platform = platform;
      // BuiltInConverters是一个内置的数据转换器工厂(继承Converter.Factory类)
      converterFactories.add(new BuiltInConverters());
    }

    public Builder() {
      // 去获取平台
      this(Platform.get());
    }
}


// Platform类
class Platform {
 // 单例获取平台 
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    try {
     // JVM加载如果有此类,表示是Android平台
      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平台
  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);
    }
	// MainThreadExecutor会创建一个主线程的Handler,所以回调任务会在主线程中执行
    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }
}
2、baseUrl().addCallAdapterFactory仅仅只是往Builder里添加参数
public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      List<String> pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      // 赋值给Builder的成员变量baseUrl 
      this.baseUrl = baseUrl;
      return this;
    }

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

    /**
     * Add a call adapter factory for supporting service method return types other than {@link
     * Call}.
     */
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
}
3、build()创建Retrofit
// Builder类的build方法
public Retrofit build() {
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
       // 创建一个默认的OKHttpClient
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
       // 平台的回调执行器,上面分析过了,即是MainThreadExecutor 
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // 这时候这里会有两个CallAdapter.Factory
      // 第一个是我们外部添加的RxJava2CallAdapterFactory
      // 第二个是Android平台里创建的ExecutorCallAdapterFactory
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      // 这里也会有两个Converter.Factory
      // 第一个是Builder创建时添加的BuiltInConverters
      // 第二个是我们外部添加的GsonConverterFactory
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
      
	  // 创建Retrofit,把参数赋值给Retrofit的成员变量
      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
}

// Retrofit的构造方法
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
    this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }

至此,Retrofti对象已创建完毕。
Retrofit使用建造者模式通过Builder类建立了一个Retrofit实例,具体创建细节是配置了:
(1)平台类型对象(Platform - Android)
(2)网络请求的url地址(baseUrl)
(3)网络请求工厂(callFactory)- 默认OKHttpClient
(4)网络请求适配器工厂的集合(adapterFactories)
(5)数据转换器工厂的集合(converterFactories)
(6)回调方法执行器(callbackExecutor)

二、ApiService sevice = retrofit.create(ApiService.class);

public interface ApiService {
    /**
     * 最简单的GET请求,无参数
     */
    @GET("api/fetch/guesslike")
    Call<GuessLikeEntity> getInfo1();
}
// Retrofit类的create方法
public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
     // validateEagerly默认是false
     // eagerlyValidateMethods方法表示提前解析ApiService文件,而不是默认的动态去解析。
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    // Proxy就很熟悉了,动态代理。有一个动态代理类去代理ApiService接口
    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);
            }
            // 注解解析的核心在这,首先我们看loadServiceMethod方法 ==> (1)
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            // 封装到OKHttpCall里 ==>(2)
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            // (3)
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
}

通过上面源码可知,我们拿到的ApiService对象其实是一个代理对象。

三、Call call = service.getInfo1();

当这个代理对象调用其里的方法时,会回调执行动态代理创建时的InvocationHandler类的invoke方法

// 先来看(1),Retorift的loadServiceMethod方法
// 享元模式,增加了内存缓存机制。如果有,则直接从serviceMethodCache里取,没有则去创建ServiceMethod
ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
       // 依然是通过Builder模式去创建ServiceMethod
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
}
// ServiceMethod类的静态内部类Builder类
static final class Builder<T, R> {
    Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit; 
      this.method = method; // 外面传进来的method对象
      // 获取方法的注解
      this.methodAnnotations = method.getAnnotations(); 
       // 获取方法的参数类型
      this.parameterTypes = method.getGenericParameterTypes();
      // 获取方法的参数注解
      this.parameterAnnotationsArray = method.getParameterAnnotations(); 
   }
}

// build方法
public ServiceMethod build() {
      // (4)
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();
      responseConverter = createResponseConverter();
	  // 遍历该方法的所有注解
      for (Annotation annotation : methodAnnotations) {
        // (5)解析这个注解
        parseMethodAnnotation(annotation);
      }
	  // 开始解析参数注解 
      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.");
        }
        // (6)解析注解参数
        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }
      return new ServiceMethod<>(this);
}
// 先来看(4)
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
        // 最终调用retrofit的callAdapter方法
        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);
      }
}

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

// Retrofit的nextCallAdapter方法
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    // 遍历Retrofit的成员变量adapterFactories,也就是我们我们Retrofi.build方法里分析的
    // 第一个是我们外部添加的RxJava2CallAdapterFactory
    // 第二个是Android平台里创建的ExecutorCallAdapterFactory
    // 所以这里返回的就是我们外部设置的CallAdapter
    int start = adapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
}
// 接着来看(5)
// 这个方法会根据注解,获取其请求类型(GET/POST/PUT/DELETE等),获取其请求的地址以及是否有body
// 解析到这些数据后,设置到Builder的成员变量里httpMethod、relativeUrl和hasBody里
private void parseMethodAnnotation(Annotation annotation) {
      if (annotation instanceof DELETE) {
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
      } else if (annotation instanceof GET) {
        parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
      } else if (annotation instanceof HEAD) {
        parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
        if (!Void.class.equals(responseType)) {
          throw methodError("HEAD method must use Void as response type.");
        }
      } else if (annotation instanceof PATCH) {
        parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
      } else if (annotation instanceof POST) {
        parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
      } else if (annotation instanceof PUT) {
        parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
      } else if (annotation instanceof OPTIONS) {
        parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
      } else if (annotation instanceof HTTP) {
        HTTP http = (HTTP) annotation;
        parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
      } else if (annotation instanceof retrofit2.http.Headers) {
        String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
        if (headersToParse.length == 0) {
          throw methodError("@Headers annotation is empty.");
        }
        headers = parseHeaders(headersToParse);
      } else if (annotation instanceof Multipart) {
        if (isFormEncoded) {
          throw methodError("Only one encoding annotation is allowed.");
        }
        isMultipart = true;
      } else if (annotation instanceof FormUrlEncoded) {
        if (isMultipart) {
          throw methodError("Only one encoding annotation is allowed.");
        }
        isFormEncoded = true;
      }
}
// 方法(6)
// 把参数注解(比如@Query @Field)等解析后封装到Builder的成员参数ParameterHandler
private ParameterHandler<?> parseParameter(
        int p, Type parameterType, Annotation[] annotations) {
      ParameterHandler<?> result = null;
      for (Annotation annotation : annotations) {
        ParameterHandler<?> annotationAction = parseParameterAnnotation(
            p, parameterType, annotations, annotation);

        if (annotationAction == null) {
          continue;
        }
        if (result != null) {
          throw parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
        }
        result = annotationAction;
      }
      if (result == null) {
        throw parameterError(p, "No Retrofit annotation found.");
      }
      return result;
}
// 回头分析(2)
// 创建一个OkHttpCall,其参数是serviceMethod和args
final class OkHttpCall<T> implements Call<T> {
  private final ServiceMethod<T, ?> serviceMethod;
  private final @Nullable Object[] args;
  private volatile boolean canceled;
  @GuardedBy("this")
  private @Nullable okhttp3.Call rawCall;
  @GuardedBy("this")
  private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException.
  @GuardedBy("this")
  private boolean executed;

  OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }
}

// 回头分析(3)
// 假设我们外部没有设置RxJava2CallAdapter类
// 那么就会调用ExecutorCallAdapterFactory类匿名内部类CallAdapter
return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }
	  // 外部调用adapt的方法
      @Override public Call<Object> adapt(Call<Object> call) {
        // 其callbackExecutor即为Platform里的MainThreadExecutor
        // call即为OkHttpCall
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
};

这一步主要工作就是,解析ApiService代理对象里的方法注解和参数注解,并且创建一个OKHttpCall对象。

四、call.enqueue();

// 此时这里的call即为上面创建的ExecutorCallbackCall对象
// ExecutorCallbackCall类的enqueue方法
@Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");
      // delegate是OkHttpCall,最终调用OKHttpCall的enqueue方法
      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);
            }
          });
        }
      });
}
// OkHttpCall类的enqueue方法
@Override public void enqueue(final Callback<T> callback) {
    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 {
         // 创建一个okhttp的call对象
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          failure = creationFailure = t;
        }
      }
    }

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

    if (canceled) {
      call.cancel();
    }
	// 调用OKHttp的异步请求方法
    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();
        }
      }
    });
}
// 创建OKHttp的call对象
private okhttp3.Call createRawCall() throws IOException {
	// ServiceMethod类会通过建造模式创建出一个OKHttp的Request,
	// 相当于把请求方法,请求URL,参数等传递给OKHttp的RequestBuilder来构建出Request对象
    Request request = serviceMethod.toRequest(args);
    // 上面分析过了callFactory即为OKHttpClient
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

最后一步,就是吧解析的出来的注解、参数转换成OKHttp需要的请求参数,去调用OKHttp的请求。
至此,Retrofit的主流程已分析完毕。
Retrofit流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值