Retrofit2源码解析

本篇文章基于 retrofit2 的 2.5.0 版本。


首先我们想要分析源码,那就首先要会使用。看下简单用法:

public interface GitHubService {
    @GET("users/{user}/repos")
    Call> listRepos(@Path("user") String user);
}
//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .build();
//创建service
GitHubService service = retrofit.create(GitHubService.class);
//创建Call
Call> repos = service.listRepos("octocat");
//开始请求
repos.enqueue(new Callback>() {
    @Override
    public void onResponse(Call> call, Response> response) {

    }
    @Override
    public void onFailure(Call> call, Throwable t) {

    }
});

1.

从create方法入手,发现是动态代理。
调用Platform.get获取platform,暂时不知道是干嘛的,
接着看核心方法是loadServiceMethod(method).invoke(..);

Retrofit2源码解析_第1张图片
image.png

2.

进入loadServiceMethod方法中,找到核心方法parseAnnotations()。从方法名上看出是解析注解的意思。

Retrofit2源码解析_第2张图片
image.png

3.

进入parseAnnotations方法中,有两处核心代码。

RequestFactory.parseAnnotations(retrofit, method);

HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);

Retrofit2源码解析_第3张图片
image.png

4.

先查看第一处核心代码RequestFactory.parseAnnotations(retrofit, method);
发现是使用了Builder模式创建了RequestFactory对象,看里面的方法,发现有一个create方法可以使用,进入方法里面。

Retrofit2源码解析_第4张图片
image.png
Retrofit2源码解析_第5张图片
image.png
  • 先看第一段代码RequestBuilder,查看类里面的方法,字面意思是quest的构造器。
    Retrofit2源码解析_第6张图片
    image.png
  • 再看第二段代码,用刚才的RequestBuilder对象创建了一个okhttp3.Request对象。查看里面的方法。知道大概是一个真正用来发起请求的类。先记着,还没有用到。
    Retrofit2源码解析_第7张图片
    image.png

5.

现在回到第3个步骤继续。查看第二处核心代码HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);

Retrofit2源码解析_第8张图片
image.png

看注释可以了解到,ServiceMethod最好缓存起来使用,这样就能解释上面第2个步骤的缓存了。接着往下看核心代码:
①创建了CallAdapter。

追踪方法得知最终是由Retrofit对象的nextCallAdapter方法获取,内部是从callAdapterFactories这个List中取出,由于还没有查看Retrofit类的实现,暂时先放着。

②创建了ResponseConverter

追踪方法最终还是由Retrofit对象的nextResponseBodyConverter方法获取,与上一个类似,从converterFactories中取出,还是先放着。

③获取callFactory

这个更直接,从retrofit中取出成员变量callFactory。

④传入4个参数,创建一个HttpServiceMethod对象

最后看看HttpServiceMethod的构造方法,发现只是设置了变量。

6.

回到最初开始分析时的代码loadServiceMethod(method).invoke(..);
loadServiceMethod(method)实际上返回了HttpServiceMethod对象,查看里面的invoke方法。

image.png

其中4个变量都是构造方法传进来的,继续查看 callAdapter.adapt方法。发现是一个接口方法。

T adapt(Call call);

现在需要找到CallAdapter实现类。从上一步骤知道,这里的4个成员变量callAdapter,requestFactory,callFactory,responseConverter中除了requestFactory是刚才知道怎么创建的,其他都是从Retrofit对象中取出来的。

7.

现在需要知道Retrofit对象是怎么构建的,回到最初的简单用法中得知,Retrofit是从Retrofit.Builderbuild方法创建的。

//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .build();

8.

现在从build方法入手。

/**
 * Create the {@link Retrofit} instance using the configured values.
 * 

* Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link * OkHttpClient} will be created and used. */ 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 callAdapterFactories = new ArrayList<>(this.callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); // Make a defensive copy of the converters. List converterFactories = new ArrayList<>( 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize()); // 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); converterFactories.addAll(platform.defaultConverterFactories()); return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); }

先看注释,明白这里就是通过一些配置来创建一个Retrofit对象,即Builder模式。
看到callFactory的创建,默认是一个OkHttpClient对象,这一点注释也有说明。
创建了一个Executor,使用了platform的defaultCallbackExecutor方法。
创建了一个callAdapterFactories的List,把默认的CallAdapterFactories添加进去,还是使用了platform的方法,defaultCallAdapterFactories(callbackExecutor)。
类似的实现方式,创建了converterFactories,也是添加了默认的对象。
最后创建了一个Retrofit对象并返回,把参数设置到了对象中。

现在清楚了第6步骤使用的对象都是在Retrofit创建时就已经配置好了,但是我们继续查看时,发现它们都是接口,所以我们需要找出它们的实际对象,即是要找出它们实例化的代码。

9.

由于默认的Executor,CallAdapter,ConverterFactories都是由Platform的defaultXXXX方法创建的,所以分析一下platform这个对象其实是什么。回到第一步骤,Retrofit的create方法的return中的一行代码。

private final Platform platform = Platform.get();

进去看看

private static final Platform PLATFORM = findPlatform();//获取平台

static Platform get() {
  return PLATFORM;
}

private static Platform findPlatform() {
  try {
    Class.forName("android.os.Build");
    if (Build.VERSION.SDK_INT != 0) {
      return new Android();//这里看到Platform对象其实就是Android对象
    }
  } catch (ClassNotFoundException ignored) {
  }
  try {
    Class.forName("java.util.Optional");
    return new Java8();
  } catch (ClassNotFoundException ignored) {
  }
  return new Platform();
}

现在知道了platform其实就是Android对象,我们查看Retrofit的build方法里的platform的调用:

  • callbackExecutor = platform.defaultCallbackExecutor();
  • platform.defaultCallAdapterFactories(callbackExecutor)
  • platform.defaultConverterFactoriesSize()
  • platform.defaultConverterFactories()
static class Android extends Platform {
  @IgnoreJRERequirement // Guarded by API check.
  @Override boolean isDefaultMethod(Method method) {
    if (Build.VERSION.SDK_INT < 24) {
      return false;
    }
    return method.isDefault();
  }

  //①默认的Executor是MainThreadExecutor
  @Override public Executor defaultCallbackExecutor() {
    return new MainThreadExecutor();
  }

  //②默认的CallAdapterFactories
  @Override List defaultCallAdapterFactories(
      @Nullable Executor callbackExecutor) {
    if (callbackExecutor == null) throw new AssertionError();
    //CallAdapterFactory的默认对象,传入了callbackExecutor
    ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
    return Build.VERSION.SDK_INT >= 24
      ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
      : singletonList(executorFactory);
  }

  //默认的CallAdapterFactoriesSize
  @Override int defaultCallAdapterFactoriesSize() {
    return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
  }

  //④默认的ConverterFactories
  @Override List defaultConverterFactories() {
    return Build.VERSION.SDK_INT >= 24
        ? singletonList(OptionalConverterFactory.INSTANCE)
        : Collections.emptyList();
  }

  //③默认的ConverterFactoriesSize
  @Override int defaultConverterFactoriesSize() {
    return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
  }

  //默认的Executor中的execute方法就是用handler发消息,把操作放到主线程中
  static class MainThreadExecutor implements Executor {
    private final Handler handler = new Handler(Looper.getMainLooper());

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

10.

现在回看第5个步骤,发现了使用的参数都是由这里的对象中取出的,那么可以继续分析第6步骤的方法:


image.png

callAdapter的获取,在nextCallAdapter方法中
核心callAdapterFactories.get(i).get(returnType, annotations, this);

public CallAdapter nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
    Annotation[] annotations) {
  ...

  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;
    }
  }
  ...
}

上面知道了callAdapterFactories的默认实现就是ExecutorCallAdapterFactory,进入该类查看get方法。

@Override public @Nullable CallAdapter get(
    Type returnType, Annotation[] annotations, Retrofit retrofit) {
  ...
  //创建了一个CallAdapter
  return new CallAdapter>() {
    @Override public Type responseType() {
      return responseType;
    }

    //核心方法
    @Override public Call adapt(Call call) {
      return new ExecutorCallbackCall<>(callbackExecutor, call);
    }
  }; 
}
 
 

到这里其实就是callAdapter的实现了。

11.

继续查看adapt方法,前文得知传入的call就是new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
查看内部类ExecutorCallbackCall:

Retrofit2源码解析_第9张图片
image.png

我们使用时就是调用了Call的enqueue方法,这里看到enqueue方法的真正实现。
其中delegate是刚才传入的OkHttpCall对象,callbackExecutor我们知道其实是MainThreadExecutor对象,所以这里的enqueue方法中主要做了两件事:

  • 调用OkHttpCall的enqueue发起请求
  • 调用MainThreadExecutor的execute方法,内部其实就是用主线程的Handler切换到主线程去运行。

我们继续查看OkHttpCall的enqueue方法:

@Override public void enqueue(final Callback 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 {
        //创建okhttp3.Call对象
        call = rawCall = createRawCall();
      } catch (Throwable t) {
        throwIfFatal(t);
        failure = creationFailure = t;
      }
    }
  }

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

  if (canceled) {
    call.cancel();
  }
  //调用了okhttp3.Call对象的enqueue方法
  call.enqueue(new okhttp3.Callback() {
    @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
      Response response;
      try {
        response = parseResponse(rawResponse);
      } catch (Throwable e) {
        throwIfFatal(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();
      }
    }
  });
}

发现很长,其实里面的主要工作就是:

  • 创建okhttp3.Call的对象
  • 调用这个对象的enqueue方法

我们来看一下这个okhttp3.Call对象是什么,查看createRawCall()方法:

private okhttp3.Call createRawCall() throws IOException {
  //这个callFactory其实就是okhttpClient
  okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
  if (call == null) {
    throw new NullPointerException("Call.Factory returned null.");
  }
  return call;
}

由上文得知这里的callFactory就是Retrofit.build()中创建的OkhttpClient对象。
这里的newCall方法就是创建一个OkHttp的Call了,所以说Retrofit是基于OkHttp来实现的。

@Override public Call newCall(Request request) {
  return RealCall.newRealCall(this, request, false /* for web socket */);
}

总结

  1. 调用Retrofit.Builder的build方法,初始化必要的参数。
    有baseUrl、callFactory、callbackExecutor、callAdapterFactories、converterFactories等。
  2. 调用retrofit的create方法,包装出一个自定义的接口GitHubService的Class。
    内部实现是动态代理,具体实现是HttpServiceMethod的对象。其中包含了对接口方法注解的解析。
  3. 最后调用enqueue发起请求内部使用了okhttp。

谢谢大家能看到末尾,如果发现有错误的地方或者有疑问的地方请各位留言,谢谢!

你可能感兴趣的:(Retrofit2源码解析)