博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Retrofit2.0- 源码分析
阅读量:6757 次
发布时间:2019-06-26

本文共 14138 字,大约阅读时间需要 47 分钟。

1. 阅读引导

在分析 源码之前,你首先得理解动态代理模式,因为Retrofit是通过动态代理的方式进行统一网络请求接口类的处理。Retrofit的代码量并不大,只是对OkHttp进行了封装,用更少的代码进行网络请求,明白动态代理模式之后,再看Retrofit网络请求处理流程就很清楚了。少量的代码使用大量的设计模式,所以Retrofit框架很值得我们去研究。

2. Retrofit基本使用

  1. 配置Retrofit对象(与OkHttp相同,采用Builder模式)

Retrofit retrofit = new Retrofit.Builder().baseUrl("xxxxx").build();

  1. 创建请求接口类
public interface NetworkInterface {        @GET("...")    Call
listRepos(); //不同的方法代表不同的网络请求,可以声明请求方式(GET、POST..),请求头Header参数,请求体信息。 ....}复制代码
  1. 创建接口类实例

NetworkInterface networkInterface = retrofit.create(NetworkInterface.class);

  1. 调用方法,请求实际的网络请求
Call
call = networkInterface.listRepos(); call.enqueue(new Callback
() { //与OkHttp不同,异步请求会回调到主线程 @Override public void onResponse(Call
call, Response
response) { } @Override public void onFailure(Call
call, Throwable t) { } });复制代码

3. Retrofit流程图

说明: Retrofit只存在一个CallFactory,但是存在多个CallAdapterFactory和ConvertFactory,针对不同的请求接口方法,Retrofit会通过其返回值,选择特定的CallAdapterFactory和CovertFactory。

4. Retrofit源码分析

4.1 Retrofit创建过程

通过前面基本的使用代码可以看出,Retrofit的创建也是采用Builder设计模式,通过new Retrofit.Builder().build()。我们先看看new Retrofit.Builder()的初始化工作。

public static final class Builder {  ...    public Builder() {      this(Platform.get());    }   Builder(Platform platform) {      converterFactories.add(new BuiltInConverters());    }  ...}复制代码

通过Platform.get()获取当前平台对象Platform,然后调用它的另一个构造器,在这个构造器中,为ConvertFactory集合添加一个默认的ConvertFactory,不同的ConvertFactory产生的Convert对OkHttp网络请求返回的Response转化处理不一样,而默认ConvertFactory的Convert并没有对Response做太多处理,获得的数据依旧是Response对象。通过Builder.addConverterFactory(xxx)添加更多的ConvertFactory,比如xxx替换为GsonConverterFactory.create()添加GsonConvertFatory,它产生的GsonConvert就能将Response映射成JavaBean实体。

回到主流程,还是看看Platform.get()是如何处理的吧!

class Platform {  private static final Platform PLATFORM = findPlatform();        //  静态工厂模式!  static Platform get() {    return PLATFORM;  }  private static Platform findPlatform() {     // 识别当前平台,如果是Android,就直接返回Android()对象实例    try {      Class.forName("android.os.Build");      if (Build.VERSION.SDK_INT != 0) {        return new Android();      }    } catch (ClassNotFoundException ignored) {    }     ...       static class Android extends Platform {                    // Platform的子类,Android平台对象类    @Override public Executor defaultCallbackExecutor() {      return new MainThreadExecutor();    }    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {   // 获取Android平台的默认CallAdapterFactory对象      if (callbackExecutor == null) throw new AssertionError();      return new ExecutorCallAdapterFactory(callbackExecutor);    }    static class MainThreadExecutor implements Executor {       // 获取Android平台的默认线程执行调度器,其实就是通过Handler用于线程切换。      private final Handler handler = new Handler(Looper.getMainLooper());      @Override public void execute(Runnable r) {        handler.post(r);      }    }  }    }复制代码

总结: 通过new Retrofit.Builder()为ConvertFactory集合中添加一个默认ConvertFactory,创建一个包含默认的CallAdapterFactory、Executor的Android平台对象。注意,默认的ConvertFactory已经添加到了ConvertFactory集合中了,但是Android对象中的CallAdapterFactory并没有加入到CallAdapterFactory集合中。

接着看new Retrofit.Builder().build()中的build()方法:

public Retrofit build() {      if (baseUrl == null) {                  // 强制需要通过.baseUrl("xxxxx")配置url        throw new IllegalStateException("Base URL required.");        }      okhttp3.Call.Factory callFactory = this.callFactory;      if (callFactory == null) {        callFactory = new OkHttpClient();    // 创建CallFactory用于生产Call对象,从这里也可以看出Retrofit最终还是通过OkHttp发送网络请求      }      Executor callbackExecutor = this.callbackExecutor;      if (callbackExecutor == null) {        callbackExecutor = platform.defaultCallbackExecutor();    // 获取Android平台对象中的默认Executor,里面通过Handler进行线程切换,上面有讲过!      }      List
adapterFactories = new ArrayList<>(this.adapterFactories); // 此处将Android平台对象中的CallAdapterFactory添加到Retrofit的CallAdapterFactory集合中. // 注意同时将Executor也传入到这个CallAdapterFactory中,那么工厂生产出来的CallAdapter就也就具有线程切换的能力。 adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); List
converterFactories = new ArrayList<>(this.converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); // 通过Builder创建Retrofit,并将配置参数作为参数传入 }复制代码

再看看一下Retrofit的构造:

Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,      List
converterFactories, List
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; }复制代码
4.2 核心动态代理代码

NetworkInterface networkInterface = retrofit.create(NetworkInterface.class);

public 
T create(final Class
service) { Utils.validateServiceInterface(service); // 1. 判断网络请求接口类的合法性 if (validateEagerly) { // 2. 是否需要提前对 网络请求接口类 中的方法进行提前处理,即为接口中的每一个方法提前处理成 SeviceMethod(核心类)对象,并缓存。 eagerlyValidateMethods(service); } // 3. 生成动态代理类 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 { ... // 4. 将接口中的方法处理成serviceMethod。 ServiceMethod
serviceMethod = (ServiceMethod
) loadServiceMethod(method); OkHttpCall
okHttpCall = new OkHttpCall<>(serviceMethod, args); // 5. 创建 OkHttpCall对象,传入serviceMethod对象和调用方法实际参数。 return serviceMethod.callAdapter.adapt(okHttpCall); // 6. 将Call对象进行CallAdapter进行转化( 比如RxCallAdapter将Call转化为Observable ) 注意Call还没有被执行,即没有进行网络请求。 } }); }复制代码

总结: (一 ) retrofit.create(xx)方法中处理分三步:

    1. 判断网络请求接口类的合法性
    1. 是否需要提前对 网络请求接口类 中的方法进行预处理
    1. 返回生成动态代理类

(二) 调用网络请求接口方法,动态代理类中的invoke()方法被执行,也处理也分三步:

    1. 将对应的执行方法转化成ServiceMethod对象
    1. 创建OkHttpCall对象
  • 3 OkHttpCall通过CallAdapter进行Call的转化
4.3 调用接口方法

Call call = networkInterface.listRepos();

在通过上面的说明,当调用网络请求接口类方法时,就会调用invoke方法,传入通过反射获取Method和执行方法参数args,因为没有调用call.execute()或call.enqueue(Callback),所以Call并没有执行。接下来我们具体看看invoke方法体中三部曲吧!

    1. 将对应的执行方法转化成ServiceMethod对象
ServiceMethod
loadServiceMethod(Method method) { ServiceMethod
result = serviceMethodCache.get(method); // 先从缓存中取,如果在之前分析的create()中validateEagerly = true 必然从缓存中能取到。 if (result != null) return result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { result = new ServiceMethod.Builder<>(this, method).build(); // 根据Method创建ServiceMethod对象 serviceMethodCache.put(method, result); // 将创建的ServiceMethod进行缓存 } } return result; }复制代码

接下来看看,ServiceMethod的创建!

ServiceMethodBuilder.class

Builder(Retrofit retrofit, Method method) {      this.retrofit = retrofit;                         // 1. 将外观类 Retrofit传入      this.method = method;                             this.methodAnnotations = method.getAnnotations();  //  2. 获取方法上的注解(@GET @POST... )      this.parameterTypes = method.getGenericParameterTypes();         this.parameterAnnotationsArray = method.getParameterAnnotations();  // 3. 获取参数注解(@Query ...)    }public ServiceMethod build() {      callAdapter = createCallAdapter();               // 4. 获取该方法对应的CallAdapter      responseType = callAdapter.responseType();  //  5. 获取该方法的响应类型,比如Response或者自定义的JavaBean      ...       responseConverter = createResponseConverter();   // 6. 根据上面获取的响应类型获取对应的Convert      for (Annotation annotation : methodAnnotations) {  // 7. 解析第二步得到的方法注解        parseMethodAnnotation(annotation);      }      ...       int parameterCount = parameterAnnotationsArray.length;      parameterHandlers = new ParameterHandler
[parameterCount]; for (int p = 0; p < parameterCount; p++) { Type parameterType = parameterTypes[p]; ... Annotation[] parameterAnnotations = parameterAnnotationsArray[p]; // 8. 解析第三步得到的参数注解 ... parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations); } return new ServiceMethod<>(this); // 创建ServiceMethod对象 }复制代码

之前有说过Retrofit中可以有多个ConvertFactory和CallAdapterFactory,通过上面的第4步和第6步获取该Method对应的ConvertFactory和CallAdapterFactory。这两种Factory的适配过程近乎一样,所以这里只做CallAdapterFactory的配对过程。

private CallAdapter
createCallAdapter() { Type returnType = method.getGenericReturnType(); ... Annotation[] annotations = method.getAnnotations(); ... return (CallAdapter
) retrofit.callAdapter(returnType, annotations); }复制代码

Retrofit.class

public CallAdapter
nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { // type: return 返回的类型,比如Call、Observable ... int start = adapterFactories.indexOf(skipPast) + 1; // 用于做CallAdapterFactory跳过处理,默认start = 0 for (int i = start, count = adapterFactories.size(); i < count; i++) { CallAdapter
adapter = adapterFactories.get(i).get(returnType, annotations, this); if (adapter != null) { return adapter; } } ...}复制代码

每一个CallAdapterFactory需要实现一个get(returnType,xxx)方法,如果能处理这个returnType就返回对应的CallAdapter对象。比如默认returnType为Call,那么就被默认的CallAdapterFactory接受处理,这个CallAdapterFactory在Android平台类中defaultCallAdapterFactory()获得(4.1 Retrofit创建过程 有说明)

Android.class

@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {      if (callbackExecutor == null) throw new AssertionError();      return new ExecutorCallAdapterFactory(callbackExecutor);    }复制代码

ExecutorCallAdapterFactory.class

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); } }; }复制代码

总结: ServiceMethod通过Builder模式创建,包含了Retrofit对象,对执行的Method进行剖析,像方法注解、参数注解、参数类型、CallAdapter、ConvertAdapter,所以一个ServiceMethod对象包含了网络请求需要的所有信息。

    1. 创建OkHttpCall对象

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

OkHttpCall.class

OkHttpCall(ServiceMethod
serviceMethod, @Nullable Object[] args) { this.serviceMethod = serviceMethod; this.args = args; }复制代码
  • 3 OkHttpCall通过CallAdapter进行Call的转化

serviceMethod.callAdapter.adapt(okHttpCall);

如果接口方法返回类型是Call的话,CallAdapter就是默认的CallAdaterFactory创建的CallAdapter,即ExecutorCallAdapterFactory类中get()方法返回的CallAdapter:

new CallAdapter
>() { @Override public Type responseType() { return responseType; } @Override public Call
adapt(Call call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } };复制代码

接着定位返回的CallAdapter中adapt()方法,最后返回了一个new ExecutorCallbackCall<>(callbackExecutor, call); 对象,代表serviceMethod.callAdapter.adapt(okHttpCall);的执行结束,并向外暴露一个ExecutorCallbackCall对象。

    1. 同步异步网络请求
// 同步请求call.execute();// 异步请求call.enqueue(new Callback
() { //与OkHttp不同,异步请求会回调到主线程 @Override public void onResponse(Call
call, Response
response) { } @Override public void onFailure(Call
call, Throwable t) { } });复制代码

与同步相比,异步相对来说复杂一点点,这里只分析异步,相信异步看懂了,同步肯定不在话下。

ExecutorCallbackCall.class

@Override public void enqueue(final Callback
callback) { ... delegate.enqueue(new Callback
() { // delegate是由serviceMethod.callAdapter.adapt(okHttpCall); 传入的,所以最终的网络请求还是通过OkHttpCall进行。 @Override public void onResponse(Call
call, final Response
response) { callbackExecutor.execute(new Runnable() { // callbackExecutor 是Android平台对象类中的MainThreadExecutor 主要将线程切换到主线程 @Override public void run() { if (delegate.isCanceled()) { ... } 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.class

@Override public void enqueue(final Callback
callback) { ... call.enqueue(new okhttp3.Callback() { // 这个Call才是OKHttp中正宗的Call @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) throws IOException { Response
response; try { response = parseResponse(rawResponse); } catch (Throwable e) { callFailure(e); return; } callSuccess(response); } ... }复制代码

5. Retrofit设计模式

  • Builder模式
  • 外观模式
  • 静态工厂模式
  • 动态工厂模式
  • 适配器模式
  • 动态代理模式

转载地址:http://yrweo.baihongyu.com/

你可能感兴趣的文章
【人生】新年伊始
查看>>
杭电2097--Sky数
查看>>
杭电1754--I Hate It(线段树)
查看>>
AS莫名报错 Error:Could not download junit.jar (junit:junit:4.12): No cached version available
查看>>
Kendo UI 简单使用
查看>>
FCKeditor的使用说明
查看>>
[转载]树莓派新版系统上使用mjpg-streamer获取USB摄像头和树莓派专用摄像头RaspiCamera图像...
查看>>
处理js两个数相乘的坑
查看>>
1.spring:helloword/注入/CDATA使用/其他Bean/null&级联/p命名空间
查看>>
docker-3-常用命令(上)
查看>>
Python(Dict和Set类型)
查看>>
django-pure-pagination 组件使用
查看>>
drf视图认证组件
查看>>
HDU 5059 Help him(BestCoder Round #12)
查看>>
PE Header中的FIleHeader(文件头)
查看>>
I/O异步之I/O完成端口
查看>>
[Asp.net]使用flexpaper+swftools大文件分页转换实现在线预览
查看>>
遇见requestAnimationFrame
查看>>
DB2 runstats、reorgchk、reorg 命令【转载】
查看>>
到底该如何理解DevOps这个词
查看>>