按照分析源码流程的“套路”,我们先来个例子:

Api

public interface SearchApi {    @GET("/search")    Call> search(@Query("key") String key);}

使用

Retrofit retrofit = new Retrofit.Builder()                    .baseUrl("http://api.example.come")                    .addConverterFactory(GsonConverterFactory.create())                    .client(new OkHttpClient())                    .build();SearchApi api = retrofit.create(SearchApi.class);Call> searchResultsCall = api.search("retrofit");searchResultsCall.enqueue(new Callback>() {    @Override    public void onResponse(Response> response, Retrofit retrofit) {        // 成功    }    @Override    public void onFailure(Throwable t) {        // 失败    }});

接下来我们一步一步来看源码。

创建Retrofit

Retrofit retrofit = new Retrofit.Builder()                    .baseUrl("http://api.example.come")                    .addConverterFactory(GsonConverterFactory.create())                    .client(new OkHttpClient())                    .build();

Retrofit.Builder,很熟悉,这不就是“建造者模式”吗?的确是!!我们来看看源码的实现:

public final class Retrofit {  private final Map serviceMethodCache = new LinkedHashMap<>();  private final okhttp3.Call.Factory callFactory;  private final HttpUrl baseUrl;  private final List converterFactories;  private final List adapterFactories;  private final Executor callbackExecutor;  private final boolean validateEagerly;  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,      List converterFactories, List adapterFactories,      Executor callbackExecutor, boolean validateEagerly) {    this.callFactory = callFactory;    this.baseUrl = baseUrl;    this.converterFactories = unmodifiableList(converterFactories);    this.adapterFactories = unmodifiableList(adapterFactories);    this.callbackExecutor = callbackExecutor;    this.validateEagerly = validateEagerly;  }  ...  // Retrofit其他方法  ...  /**   * Retrofit 建造者   **/  public static final class Builder {    private Platform platform;    private okhttp3.Call.Factory callFactory;    private HttpUrl baseUrl;    private List converterFactories = new ArrayList<>();    private List adapterFactories = new ArrayList<>();    private Executor callbackExecutor;    private boolean validateEagerly;    Builder(Platform platform) {      this.platform = platform;      converterFactories.add(new BuiltInConverters());    }    public Builder() {      this(Platform.get());    }    ...    // 各种set方法    ...    // build方法    public Retrofit build() {      ...      // 各种属性初始化      ...      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,          callbackExecutor, validateEagerly);    }  }}

这样,我们就把Retrofit给build出来了,至于各种属性,等到解析到了再一一分析,不急。

创建Api接口代理对象

SearchApi api = retrofit.create(SearchApi.class);

接着调用 retrofit.create(SearchApi.class) 方法,创建出SearchApi的对象!这是Retrofit比较精彩的地方,我们来看看,Retrofit怎么做到由一个接口创建一个对象:

public final class Retrofit {  ...  // Retrofit其他方法  ...  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, 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 serviceMethod = loadServiceMethod(method);            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);            return serviceMethod.callAdapter.adapt(okHttpCall);          }        });  }  ...  // Retrofit其他方法  ...}

原来使用了“动态代理模式”,很妙吧!我们再深入了解一下这个方法。

拦截方法,解析注解

Call> searchResultsCall = api.search("retrofit");

当执行api接口代理的某个方法时,开始拦截,单独看InvocationHandler里面做了什么:

private final Platform platform = Platform.get();@Override public Object invoke(Object proxy, Method method, Object... args)    throws Throwable {  // 如果方法时Object的方法 直接执行 一般我们Api方法返回的要么是Call类型要么是Observable类型 所以这里直接跳过  if (method.getDeclaringClass() == Object.class) {    return method.invoke(this, args);  }  // AndroidPlatform这个方法是false 直接跳过  if (platform.isDefaultMethod(method)) {    return platform.invokeDefaultMethod(method, service, proxy, args);  }  ServiceMethod serviceMethod = loadServiceMethod(method);  OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);  return serviceMethod.callAdapter.adapt(okHttpCall);}});

我们先来看看Platform是什么东西:

class Platform {  private static final Platform PLATFORM = findPlatform();  /**   * 获取平台   */  static Platform get() {    return PLATFORM;  }  /**   * 根据信息获取对应平台 这里我们只要关注Android平台就行 至于Java8和IOS 有时间自己研究   */  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) {    }    try {      Class.forName("org.robovm.apple.foundation.NSObject");      return new IOS();    } catch (ClassNotFoundException ignored) {    }    return new Platform();  }  /**   * 顾名思义 回调执行的地方 Android平台有重写这个方法    */  Executor defaultCallbackExecutor() {    return null;  }  CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {    if (callbackExecutor != null) {      return new ExecutorCallAdapterFactory(callbackExecutor);    }    return DefaultCallAdapterFactory.INSTANCE;  }  /**   * Android平台没有重写这个方法 所以是false   */  boolean isDefaultMethod(Method method) {    return false;  }  Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, Object... args)      throws Throwable {    throw new UnsupportedOperationException();  }  /**   * Android 平台   **/  static class Android extends Platform {    @Override public Executor defaultCallbackExecutor() {      return new MainThreadExecutor();    }    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {      return new ExecutorCallAdapterFactory(callbackExecutor);    }    /**     * 你可以看成一个MainLooper的Handler     */    static class MainThreadExecutor implements Executor {      private final Handler handler = new Handler(Looper.getMainLooper());      @Override public void execute(Runnable r) {        handler.post(r);      }    }  }   ...   // 其他2个平台 暂时不关注   ...}

代码已加上注释,相信大家应该看得懂,上面还有个类不是很清楚,就是ExecutorCallAdapterFactory这个类,我们等用到的时候再去分析。好,Platform大概了解到这里,我们继续。经过2个判断后,调用了loadServiceMethod方法生成ServiceMethod,我们还是看源码:

ServiceMethod loadServiceMethod(Method method) {  ServiceMethod result;  synchronized (serviceMethodCache) {    // 先从Map中取 如果为null 再去new一个出来(准确来说,是build一个出来)    // 毕竟new一个出来是利用反射的 性能上多少都会受点影响 所以要缓存起来 这样更快    result = serviceMethodCache.get(method);    if (result == null) {      result = new ServiceMethod.Builder(this, method).build();      serviceMethodCache.put(method, result);    }  }  return result;}

我们可以看出,ServiceMethod又是使用了“建造者模式”,我们来看看Builder做了什么:

static final class Builder {    final Retrofit retrofit;    final Method method;    final Annotation[] methodAnnotations;    final Annotation[][] parameterAnnotationsArray;    final Type[] parameterTypes;    Type responseType;    boolean gotField;    boolean gotPart;    boolean gotBody;    boolean gotPath;    boolean gotQuery;    boolean gotUrl;    String httpMethod;    boolean hasBody;    boolean isFormEncoded;    boolean isMultipart;    String relativeUrl;    Headers headers;    MediaType contentType;    Set relativeUrlParamNames;    ParameterHandler<?>[] parameterHandlers;    Converter responseConverter;    CallAdapter<?> callAdapter;    public Builder(Retrofit retrofit, Method method) {      this.retrofit = retrofit;      this.method = method;      this.methodAnnotations = method.getAnnotations();      this.parameterTypes = method.getGenericParameterTypes();      this.parameterAnnotationsArray = method.getParameterAnnotations();    }    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);    }}

代码很多,但是主要做了2个create和2个parse:

// 2个createcallAdapter = createCallAdapter();responseConverter = createResponseConverter();

2个create分别创建CallAdapter和ResponseConverter。
CallAdapter从名字来看,有点像“适配器模式”,我们来看看CallAdapter的源码:

public interface CallAdapter {  Type responseType();   T adapt(Call call);  // 省略适配器工厂的代码}

我们看到有个adapt方法,意思是将Retrofit的Call适配成OkHttp的Call,原因是Retrofit底层是使用OkHttp访问网络的。
我们再来看看ResponseConverter,这个从名字就知道,这是一个转化器,用于将Response转成我们需要的对象:

public interface Converter {  T convert(F value) throws IOException;  // 省略转换器工厂的代码}

接口代码很简单,我们到这里会发现,Retrofit很多地方都用到了“工厂模式”,厉害!!
2个create就分析到这里,我们再来看看2个parse。

// 2个parsefor (Annotation annotation : methodAnnotations) {  parseMethodAnnotation(annotation);}for (int p = 0; p < parameterCount; p++) {  ...  parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);}

parseMethodAnnotation主要是分析方法里面的注解。Retrofit的优势在于使用了注解,方便开发者使用。而parseParameter则是将参数解析成ParameterHandler,ParameterHandler是什么??他是一个抽象类,我们看看源码就清楚了:

abstract class ParameterHandler<T> {  abstract void apply(RequestBuilder builder, T value) throws IOException;  ...  static final class Query<T> extends ParameterHandler<T> {    private final String name;    private final Converter valueConverter;    private final boolean encoded;    Query(String name, Converter valueConverter, boolean encoded) {      this.name = checkNotNull(name, "name == null");      this.valueConverter = valueConverter;      this.encoded = encoded;    }    @Override void apply(RequestBuilder builder, T value) throws IOException {      if (value == null) return; // Skip null values.      builder.addQueryParam(name, valueConverter.convert(value), encoded);    }  }  ...}

我们从代码可以分析到,他就是一个处理器,如Query,当调用apply方法时,就会将name和value加入RequestBuilder中。这样的好处是我们第一次解析注解name出来,然后构建这么一个处理器,然后保存起来。以后调用处理器的apply方法就可以构建出RequestBuilder,不用解析多次注解。之前也说过,serviceMethodCache用于保存ServiceMethod,不用每次解析,主要保存的就是这些ParameterHandler,用于构建RequestBuilder去访问网络。
这里分析得比较细,其实主线还是挺清晰的!!

构建Retrofit的Call,然后适配成所需要的Call

Call> searchResultsCall = api.search("retrofit");

上面分析了拦截方法中,我们只分析了loadServiceMethod,还有OkHttpCall的构建和适配没有分析,接下来,我们分析一下!!

private final Platform platform = Platform.get();@Override public Object invoke(Object proxy, Method method, Object... args)    throws Throwable {  // 如果方法时Object的方法 直接执行 一般我们Api方法返回的要么是Call类型要么是Observable类型 所以这里直接跳过  if (method.getDeclaringClass() == Object.class) {    return method.invoke(this, args);  }  // AndroidPlatform这个方法是false 直接跳过  if (platform.isDefaultMethod(method)) {    return platform.invokeDefaultMethod(method, service, proxy, args);  }  // 已经分析了  ServiceMethod serviceMethod = loadServiceMethod(method);  // 构建OkHttpCall  OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);  // 适配  return serviceMethod.callAdapter.adapt(okHttpCall);}});

我们来看看OkHttpCall的构建,还是从源码看:

final class OkHttpCall<T> implements Call<T> {    ...    private okhttp3.Call rawCall;    ...}
public interface Call<T> extends Cloneable {  Response execute() throws IOException;  void enqueue(Callback callback);  boolean isExecuted();  void cancel();  boolean isCanceled();  Call clone();  Request request();}

注意,这是Retrofit自己的Call,并非Okhttp的Call,只是名字是OkHttpCall,里面持有Okhttp的Call。

我们再来看适配过程,之前也说了,这里用到了“适配器模式”,我们看看原生的适配器。这个得跟踪一下代码,原生的适配器在哪里。

首先是ServiceMethod的callAdapter:

static final class Builder<T> {  public ServiceMethod build() {    callAdapter = createCallAdapter();    ...  }  private CallAdapter<?> createCallAdapter() {      ...      try {        return 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 final class Retrofit {  ...  public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {    return nextCallAdapter(null, returnType, annotations);  }  public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,      Annotation[] annotations) {    checkNotNull(returnType, "returnType == null");    checkNotNull(annotations, "annotations == null");    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;      }    }    // 报错  }}

nextCallAdapter方法循环adapter的工厂列表,获取CallAdapter的Factory,返回的是某一个工厂的get方法。so,我们看看工厂列表是什么时候初始化的:

public static final class Builder {  ...  private List adapterFactories = new ArrayList<>();  ...  public Builder addCallAdapterFactory(CallAdapter.Factory factory) {    adapterFactories.add(checkNotNull(factory, "factory == null"));    return this;  }    public Retrofit build() {    ...    Executor callbackExecutor = this.callbackExecutor;    if (callbackExecutor == null) {      callbackExecutor = platform.defaultCallbackExecutor();    }    List adapterFactories = new ArrayList<>(this.adapterFactories);    adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));    ...    return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,          callbackExecutor, validateEagerly);  }}

由于我们构建Retrofit时没有调用addCallAdapterFactory方法,所以只有一个platform.defaultCallAdapterFactory,我们继续跟进去看源码:

class Platform {  /**   * 我们主要看Android平台的   */  static class Android extends Platform {    @Override public Executor defaultCallbackExecutor() {      return new MainThreadExecutor();    }    @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);      }    }  }}

这里其实是new了一个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<?>>() {      @Override public Type responseType() {        return responseType;      }      @Override public  Call adapt(Call call) {        return new ExecutorCallbackCall<>(callbackExecutor, call);      }    };  }  static final class ExecutorCallbackCall<T> implements Call<T> {    ...  }}

我们一步一步拆分这个类,主要看get方法,因为get方法返回值就是适配后的CallAdapter:

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

返回的是一个新的CallAdapter,再来适配器的adapt适配方法,返回的是一个ExecutorCallbackCall:

static final class ExecutorCallbackCall implements Call {  final Executor callbackExecutor;  final Call delegate;  ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {    this.callbackExecutor = callbackExecutor;    this.delegate = delegate;  }  @Override public void enqueue(final Callback callback) {    if (callback == null) throw new NullPointerException("callback == null");    delegate.enqueue(new Callback() {      @Override public void onResponse(Call call, final Response 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 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 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 clone() {    return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());  }  @Override public Request request() {    return delegate.request();  }}

其实,ExecutorCallbackCall才是我们拦截方法最终返回的Call,这下就更清楚的了!!
顺便了解一下这个类,其实这是OkHttpCall的静态代理类,使用“静态代理模式”,至于主要的作用是什么,我们继续往下看。

执行网络异步请求enqueue方法

searchResultsCall.enqueue(new Callback>() {    @Override    public void onResponse(Response> response, Retrofit retrofit) {        // 成功    }    @Override    public void onFailure(Throwable t) {        // 失败    }});

我们从上面分析到,其实这个searchResultsCall是ExecutorCallbackCall,我们来分析一下enqueue方法:

@Override public void enqueue(final Callback callback) {  if (callback == null) throw new NullPointerException("callback == null");  delegate.enqueue(new Callback() {    @Override public void onResponse(Call call, final Response 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 call, final Throwable t) {      callbackExecutor.execute(new Runnable() {        @Override public void run() {          callback.onFailure(ExecutorCallbackCall.this, t);        }      });    }  });}

其实是调用了OkHttpCall的enqueue方法,为什么要这么做呢??其实从代码很容易看出,这个代理类的主要作用是将子线程的回调转到UI线程中,实现线程转换效果!!

我们从源码分析,callbackExecutor是什么呀?

class Platform {  /**   * 我们主要看Android平台的   */  static class Android extends Platform {    @Override public Executor defaultCallbackExecutor() {      return new MainThreadExecutor();    }    @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);      }    }  }}

其实就是拥有MainLooper的Handler,使用callbackExecutor的execute,这样就可以把子线程换到UI线程上执行了!!

小结

我们上面完整的跑了Retrofit主线的流程,经过源码分析,主要有几步:

  1. 创建Retrofit
    设计模式:建造者模式
  2. 创建Api接口代理对象
    设计模式:动态代理模式
  3. 拦截方法,解析注解
    设计模式:建造者模式、工厂模式
  4. 构建Retrofit的Call,然后适配成所需要的Call
    设计模式:适配器模式、静态代理模式
  5. 执行网络异步请求enqueue方法

还有Rxjava部分没有分析,因为加上这部分,会变得稍显复杂!有兴趣的可以自行分析!!

以上是我对Retrofit框架的分析,如有错误,请不吝赐教!!!

更多相关文章

  1. Android Gallery3d源码学习总结(一)——绘制流程drawFocusItems
  2. Android中button的onClick事件几种方法
  3. Android 关闭多个Activity的实现方法
  4. Android系统源码framework SystemUI导入eclipse编译
  5. android源码下载时,repo下载不成功的问题
  6. Android系统应用程序安装过程源码分析
  7. Android中几种延后处理事件的方法
  8. Android判断包名和类名是否存在的方法
  9. Android SDK 1.5 "--core-library" build error问题解决方法

随机推荐

  1. Fragment的快速入门
  2. Android中Handler消息传递机制
  3. 认识Android与Android环境的搭建
  4. android 仿iphone tab实现
  5. Android(安卓)MVP模式 入门
  6. android在framework层增加自己的service
  7. 关于Android(安卓)Resource的点点滴滴
  8. 【移动开发】因项目需要,今天起学习移动开
  9. [来自iPc.me] 金山 WPS Office 手机移动
  10. 2015年 - 异乡