Retrofit源码笔记

阅读源码我们从代码的调用开始分析。如有错误请指正,不喜勿喷!

1.依赖库

dependencies{
    //>>>>>>>>>>>> retrofit 引用retrofit OkHttp也会被 自动加入
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    //看需要添加 RxJava
    implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
    //看需要添加 切换到主线程 
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    //implementation 'io.reactivex.rxjava3:rxjava:3.0.0'   
    //看需要添加
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    //看需要添加 日志的拦截器 
    implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.6'
    //>>>>>>>>>>>> retrofit
}

2.创建Retrofit

val retrofit = Retrofit.Builder().build()

我们现在来看下Buidler这个类

public static final class Builder {
    //运行平台 platform =Android()
    private final Platform platform;
    //OkHttpClient 对象
    private @Nullable okhttp3.Call.Factory callFactory;
    //baseUrl 通过 Builder().parse(null, this).build() 构建HttpUrl对象
    private @Nullable HttpUrl baseUrl;
    //数据转换器集合
    private final List<Converter.Factory> converterFactories = new ArrayList<>();

    //Call适配器集合 如转换成RxJava Observable<T>
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    //线程切换 如没设置默认是MainThreadExecutor()通过handler切换到主线程
    private @Nullable Executor callbackExecutor;
    //true:提前对接口方法进行解析 
    private boolean validateEagerly;

    Builder(Platform platform) {
      this.platform = platform;
    }

    public Builder() {
      //判断运行平台
      this(Platform.get());
    }
    .....
}

class Platform {
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    return "Dalvik".equals(System.getProperty("java.vm.name"))
        ? new Android() //Android平台
        : new Platform(true);
  }
}

class Android extends Platform {
    ....
    @Override
    public Executor defaultCallbackExecutor() {
       
      return new MainThreadExecutor();
    }  
    .....
    static final class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override
      public void execute(Runnable r) {
        //通过handler post到主线程
        handler.post(r);
      }
    }
  }

接下来看下 build()做什么

public Retrofit build() {
     ...
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }
    
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        //默认 MainThreadExecutor()
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      
    //默认CallAdapter.Factory的实现是 DefaultCallAdapterFactory(callbackExecutor)
           
    callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

       //添加转换器  
      // Make a defensive copy of the converters.
      List<Converter.Factory> 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);
    }

3.网络接口实例的创建

interface IServerAPI {
    @GET("users/{username}")
    fun getUser(@Path("username") username: String?): Call<User>
}

val iServerAPI = reterfit.create(IServerAPI::class.java)

现在我们来看下create到底做什么?传入接口 给我们返回一个对象。

public <T> T create(final Class<T> service) {
    //接口校验 
    validateServiceInterface(service);
    return (T)
        Proxy.newProxyInstance(//动态反射
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
              private final Platform platform = Platform.get();
              private final Object[] emptyArgs = new Object[0];

              @Override
              public @Nullable 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);
                }
                args = args != null ? args : emptyArgs;
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }




 对传入的接口信息 进行校验 我们看下都校验了什么 validateServiceInterface(service)

 private void validateServiceInterface(Class<?> service) {
   //如果不是接口就抛出异常
 if (!service.isInterface()) {
      throw new IllegalArgumentException("API declarations must be interfaces.");
    }

    Deque<Class<?>> check = new ArrayDeque<>(1);
    check.add(service);
    while (!check.isEmpty()) {
      Class<?> candidate = check.removeFirst();
       //不能是泛型接口
      if (candidate.getTypeParameters().length != 0) {
        StringBuilder message =
            new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
        if (candidate != service) {
          message.append(" which is an interface of ").append(service.getName());
        }
        throw new IllegalArgumentException(message.toString());
      }
       
      Collections.addAll(check, candidate.getInterfaces());
    }
    
    //初始化的时候默认是false 默认是不执行的 
    if (validateEagerly) { 
      Platform platform = Platform.get();
      for (Method method : service.getDeclaredMethods()) {
        if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
          loadServiceMethod(method);
        }
      }
    }
  }

那么我们看下这个validateEagerly=true的时候 loadServiceMethod(method) 执行些什么操作

ServiceMethod<?> loadServiceMethod(Method method) {
    //缓存中获取ServiceMethod
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        //解析接口中的方法 封装ServiceMethod 缓存起来
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

我们现在看下这个ServiceMethod.parseAnnotations(this, method)是怎么解析的

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    ...
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract @Nullable T invoke(Object[] args);
}

接着调用RequestFactory.parseAnnotations(retrofit, method)

final class RequestFactory {

  //接口方法
  private final Method method;
  //https://www.xx.xxx/ 封装对象
  private final HttpUrl baseUrl;
  //请求方式 GET、POST...
  final String httpMethod;
  //网络请求相对路径 user/info/
  private final @Nullable String relativeUrl;
  //协议头信息
  private final @Nullable Headers headers;
  //文件下载上传Media类型
  private final @Nullable MediaType contentType;
  //是否有Body
  private final boolean hasBody;
  //post  是否是表单数据
  private final boolean isFormEncoded;
  //post 一般用于文件请传送
  private final boolean isMultipart;
  //接口方法参数处理器
  private final ParameterHandler<?>[] parameterHandlers;
  //是否支持Kotlin
  final boolean isKotlinSuspendFunction;

  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    //RequestFactory 开始解析接口注解参数等信息
    return new Builder(retrofit, method).build();
  }
   
     static final class Builder{
        .....
         Builder(Retrofit retrofit, Method method) {
          this.retrofit = retrofit;
          this.method = method;
          //方法注解参数
          this.methodAnnotations = method.getAnnotations();
          this.parameterTypes = method.getGenericParameterTypes();
          this.parameterAnnotationsArray = method.getParameterAnnotations();
        }

        RequestFactory build() {
          for (Annotation annotation : methodAnnotations) {
            //注解解析
            parseMethodAnnotation(annotation);
          }

          if (httpMethod == null) {
            throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
          }
            
          // @FormUrlEncoded  @Multipart 只能用 POST PATCH PUT
          if (!hasBody) {
                if (isMultipart) {
                      throw methodError(
                      method,
                  "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
                }
                if (isFormEncoded) {
                  throw methodError(
                      method,
                  "FormUrlEncoded can only be specified on HTTP methods with "
                  + "request body (e.g., @POST).");
                }
           }
            
          //解析方法参数
          // Converter<F, T>.Factory中的Converter<?, String>.stringConverter(...) 
          // Converter<F, T>.Factory中的Converter<?, String>.requestBodyConverter(...) 
          //就在解析参数的时候被调用的
          int parameterCount = parameterAnnotationsArray.length;
          parameterHandlers = new ParameterHandler<?>[parameterCount];
          for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
                parameterHandlers[p] =
                parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
          }

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

          return new RequestFactory(this);
        }


        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);
              } 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(method, "@Headers annotation is empty.");
                  }
                  headers = parseHeaders(headersToParse);
              } else if (annotation instanceof Multipart) {
                  if (isFormEncoded) {
                      throw methodError(method, "Only one encoding annotation is allowed.");
             }
                    isMultipart = true;
             } else if (annotation instanceof FormUrlEncoded) {
                if (isMultipart) {
                  throw methodError(method, "Only one encoding annotation is allowed.");
                }
                isFormEncoded = true;
            }
        }


          .....
    }


 
}

从代码可以看出RequestFactory使用了Builder模式来配置,有了RequestFactory,就接着往下看HttpServiceMethod 

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    
    @Override
  final @Nullable ReturnT invoke(Object[] args) {
      //创建 OkHttpCall 封装了okhttp的网络请求
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory,         responseConverter);
    //适配的CallAapter
    return adapt(call, args);
  }

  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;

    Annotation[] annotations = method.getAnnotations();
    Type adapterType;
    if (isKotlinSuspendFunction) {
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType =
          Utils.getParameterLowerBound(
              0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response<T>.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        continuationWantsResponse = true;
      } else {
        // TODO figure out if type is nullable or not
        // Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
        // Find the entry for method
        // Determine if return type is nullable or not
      }

      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
        //方法返回类型如
        //io.reactivex.rxjava3.core.Observable<com.learn.demo.retrofit.UserInfo>
      adapterType = method.getGenericReturnType();
    }

    //从Retrofit.callAdapterFactories 集合中获取CallAdapter适配器
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    //解析返回类型的泛型类型
    //如:io.reactivex.rxjava3.core.Observable<com.learn.demo.retrofit.UserInfo>
    //callAdapter.responseType() -> class com.learn.demo.retrofit.UserInfo
    Type responseType = callAdapter.responseType();
    if (responseType == okhttp3.Response.class) {
      throw methodError(
          method,
          "'"
              + getRawType(responseType).getName()
              + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (responseType == Response.class) {
      throw methodError(method, "Response must include generic type (e.g., Response<String>)");
    }
    // TODO support Unit for Kotlin?
    if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
      throw methodError(method, "HEAD method must use Void as response type.");
    }

    //Converter.Factory.responseBodyConverter(...)
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

    //okHttpClient
    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
      //CallAdapted包装了 接口方法信息 ,okHttpClient responseConverter ,网络请求CallAdapter
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForResponse<>(
              requestFactory,
              callFactory,
              responseConverter,
              (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForBody<>(
              requestFactory,
              callFactory,
              responseConverter,
              (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
              continuationBodyNullable);
    }
  }
}

现在我们值接口方法是被封装到CallAdapter类中,我们现在回到create(..)

public <T> T create(final Class<T> service) {
  ...
    return (T)
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
 ...
                args = args != null ? args : emptyArgs;
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    //invoke(...) 返回接口方法的返回值CallAdapter对象
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }

loadServiceMethod(method).invoke(args);调用了ServiceMethod.invoke(...) -> HttpServiceMethod.invoke(...) -> CallAdapter.adapt(call, args) -> 到对应的CallAdapter的实现类中去执行。ExecutorCallbackCall 是默认的执行器,

static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
    private final CallAdapter<ResponseT, ReturnT> callAdapter;

    CallAdapted(
        RequestFactory requestFactory,
        okhttp3.Call.Factory callFactory,
        Converter<ResponseBody, ResponseT> responseConverter,
        CallAdapter<ResponseT, ReturnT> callAdapter) {
      super(requestFactory, callFactory, responseConverter);
      this.callAdapter = callAdapter;
    }

    @Override
    protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
        //默认是执行 DefaultCallAdapterFactory.adapt 
        //                    -> ExecutorCallbackCall
      return callAdapter.adapt(call);
    }
  }

final class DefaultCallAdapterFactory extends CallAdapter.Factory{

    @Override
      public @Nullable CallAdapter<?, ?> get(
          Type returnType, Annotation[] annotations, Retrofit retrofit) {
         if (getRawType(returnType) != Call.class) {
              return null;
        }
        if (!(returnType instanceof ParameterizedType)) {
          throw new IllegalArgumentException(
          "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
        }
        final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType)         returnType);

        final Executor executor =
        Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
            ? null
            : callbackExecutor;

        return new CallAdapter<Object, Call<?>>() {
              @Override
              public Type responseType() {
                    return responseType;
              }

              @Override
              public Call<Object> adapt(Call<Object> call) {
                    return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
          }
    };
}

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) {
      Objects.requireNonNull(callback, "callback == null");
        
    //delegate 是okHttpCall
      delegate.enqueue(
          new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, final Response<T> response) {
                //默认是 MainThreadExecutor 通过Handler 切换到主线程 
             callbackExecutor.execute(
                  () -> {
                    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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
            }
          });
    }

紧接OkHttpCall的enqueue

@Override
  public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(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 {
            //创建OkHttp 的 Call
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(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) {
            Response<T> response;
            try {
            
                //通过 responseConverter.convert(...)
                //转换请求回来的数据
              response = parseResponse(rawResponse);
            } catch (Throwable e) {
              throwIfFatal(e);
              callFailure(e);
              return;
            }

            try {
              callback.onResponse(OkHttpCall.this, response);
            } catch (Throwable t) {
              throwIfFatal(t);
              t.printStackTrace(); // TODO this is not great
            }
          }

          @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) {
              throwIfFatal(t);
              t.printStackTrace(); // TODO this is not great
            }
          }
        });
  }

到这里Retrofit的调用基本流程及完成了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值