Android框架源码分析——Retrofit源码分析

1、使用Demo

public static <T> T createApi(Class<T> clazz, String url) {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .client(okHttpClient)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    return retrofit.create(clazz);
}

2、源码分析

  • Retrofit.Builder():创建Builder实例初始化Retrofit
Builder(Platform platform) {
  converterFactories.add(new BuiltInConverters()); //保存默认的内置转换工厂
}
  • baseUrl():设置请求的baseUrl,程序会解析baseUrl并创建HttpUrl实例,最终实例会保存在Retrofit中
public Builder baseUrl(String baseUrl) {
  HttpUrl httpUrl = HttpUrl.parse(baseUrl); //根据baseUrl创建HttpUrl
  return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
  this.baseUrl = baseUrl; //赋值baseUrl
  return this;
}
  • create():创建API接口实例
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 {
        ServiceMethod<Object, Object> serviceMethod =  (ServiceMethod<Object, Object>) loadServiceMethod(method);  //(1)获取或创建 ServiceMethod<Object, Object>实例
        OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); //(2)创建OkHttpCall实例
        return serviceMethod.callAdapter.adapt(okHttpCall); //(3)调用设置的Adapter.adapt()转换OkHttpCall实例
      }
    });

Retrofit使用动态代理的形式拦截设置接口中的所有抽象方法,关于动态代理的内容点击查看,在动态代理的invoke()方法中主要完成以下过程:

  1. 创建ServiceMethod<Object, Object>保存方法和参数的注解信息
  2. 创建OkHttpCall实例用于执行网络请求
  3. 调用设置的CallAdapter转换OkHttp返回的Call,从而封装转换请求方式,Retrofit之所以能使用RxJava就是因为CallAdapter的存在,它可以将请求适配到任何类型上

上面的三个过程就是Retrofit的主要工作原理,下面一一分析

2.1、获取、创建ServiceMethod实例
  • Retrofit.loadServiceMethod()
ServiceMethod<?, ?> loadServiceMethod(Method method) {
  ServiceMethod<?, ?> result = serviceMethodCache.get(method);   //(1)从缓存的Map中获取ServiceMethod
  if (result != null) return result;
    synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      result = new ServiceMethod.Builder<>(this, method).build();   //(2)创建实例、解析方法和参数的注解
      serviceMethodCache.put(method, result);3)缓存ServiceMethod
    }
  }
  return result;
}

loadServiceMethod()首先从缓存中获取,如果缓存中没有则创建实例,这里设置缓存是为了当多次请求同一个接口时,避免每次都要反射获取注解,首次解析后缓存之后调用此方法时直接使用;

  • ServiceMethod.Builder——主要封装保存请求的Method、方法注解、参数类型、参数注解,具体内部属性见注解
Builder(Retrofit retrofit, Method method) {
  this.retrofit = retrofit;  //Retrofit实例
  this.method = method;   //Method方法
  this.methodAnnotations = method.getAnnotations();   //获取方法的注解类型
  this.parameterTypes = method.getGenericParameterTypes();  //获取方法的参数类型集合
  this.parameterAnnotationsArray = method.getParameterAnnotations();  //获取参数注解集合
}
  • ServiceMethod.Builder.build():创建ServiceMethod实例,解析所有的方法注解和参数注解
public ServiceMethod build() {
callAdapter = createCallAdapter(); // (1)
responseType = callAdapter.responseType(); //获取Adapter的返回类型
responseConverter = createResponseConverter(); //(2)
for (Annotation annotation : methodAnnotations) {  //(3)
  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];
  parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations); //(4)
  }
 return new ServiceMethod<>(this); //(5)
}

build()方法中执行的逻辑很多,完成了所有的转换和注解的处理,总结以下:

  1. 获取设置的Call的Adapter执行并获取转换的类型,一般设置的为RxJavaAdapter转换为Observable
  2. 获取返回类型转换器,用于对请求的结果Response进行转换
  3. 循环遍历方法的每个注解,获取请求的方法类型和请求地址
  4. 遍历参数注解,针对每个参数注解创建parameterHandlers实例封装注解信息并保存在数组中,最终使用所有的parameterHandlers创建执行网络请求
  5. 创建ServiceMethod()对象
  • parseMethodAnnotation():遍历方法注解,获取请求方式和请求的url
//遍历方法注解,确定请求方式、请求地址、请求参数
private void parseMethodAnnotation(Annotation annotation) {
  if (annotation instanceof DELETE) {
    parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);  //根据选择的方式,转换方法和参数value,并解析请求参数
  } else if (annotation instanceof GET) {
    parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);  //GET请求
  } else if (annotation instanceof POST) {
    parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);  //POST请求
}

首先根据注解解析请求方式,并获取设置的方法注解参数最终拼接请求地址,以GET方式请求为例分析,保存了请求方法GET、请求体、请求Url

private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
  this.httpMethod = httpMethod;   //保存方法“GET”
  this.hasBody = hasBody;   //是否有请求体,针对POST请求
  this.relativeUrl = value; //赋值实际请求的Url(也就是注解中的路径)
}
  • parameterAnnotationsArray():遍历方法参数注解
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];   //创建ParameterHandler实例,保存参数下标、参数类型、参数注解的解析结果
for (int p = 0; p < parameterCount; p++) {
  Type parameterType = parameterTypes[p];  //(1)
  Annotation[] parameterAnnotations = parameterAnnotationsArray[p];  //(2)获取当前参数注解
  parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);   //(3)解析参数类型和参数注解创建ParameterHandler实例,并保存在数组中
}

从上面代码看出,parameterAnnotationsArray会遍历获取所有的获取当前注解的参数类型,解析每个参数类型和参数注解创建ParameterHandler实例,并保存在数组中

  • parseParameter(): 解析参数和参数注解
private ParameterHandler<?> parseParameter( int p, Type parameterType, Annotation[] annotations) {
  ParameterHandler<?> result = null;
  for (Annotation annotation : annotations) {
    ParameterHandler<?> annotationAction = parseParameterAnnotation( p, parameterType, annotations, annotation);
    result = annotationAction;
  }
  return result;
}
  • 处理参数注解
private ParameterHandler<?> parseParameterAnnotation( int p, Type type, Annotation[] annotations, Annotation annotation) {
//处理Url注解
if (annotation instanceof Url) {
  if (gotUrl) { //Url只能出现一次,如果已经出现过了抛出异常
    throw parameterError(p, "Multiple @Url method annotations found.");
  }
  if (gotPath) { //@Path和@Url不能同时在参数注解中使用
    throw parameterError(p, "@Path parameters may not be used with @Url.");
  }
  if (gotQuery) { //@Url不能出现在@Query之后
    throw parameterError(p, "A @Url parameter must not come after a @Query");
  }
  if (relativeUrl != null) { //如果在方法注解中设置了Url,参数中不能使用@Url注解
    throw parameterError(p, "@Url cannot be used with @%s URL", httpMethod);
  }
  gotUrl = true; //此处赋值goUrl位true
  return new ParameterHandler.RelativeUrl(); //创建ParameterHandler实例,此处为实现类RelativeUrl
}
//处理Path注解
if (annotation instanceof Path) {
  if (gotQuery) { //@Path 不能出现在@Query之后
    throw parameterError(p, "A @Path parameter must not come after a @Query.");
  }
  if (gotUrl) {//@Path 和@Url不能一起使用
    throw parameterError(p, "@Path parameters may not be used with @Url.");
  }
  if (relativeUrl == null) {//使用@Path必须在方法注解中设置请求Url
    throw parameterError(p, "@Path can only be used with relative url on @%s", httpMethod);
  }
  gotPath = true; //
  Path path = (Path) annotation;
  String name = path.value(); //获取@Path注解名称,请求数据的Key
  validatePathName(p, name); //校验参数合法性
  Converter<?, String> converter = retrofit.stringConverter(type, annotations); //获取设置的String转换
  return new ParameterHandler.Path<>(name, converter, path.encoded()); //创建Path实例
}
//处理Query注解
if (annotation instanceof Query) {
  Query query = (Query) annotation;
  String name = query.value(); //获取@Query注解名称
  boolean encoded = query.encoded();
  gotQuery = true; //
    return new ParameterHandler.Query<>(name, converter, encoded);
  }
}
//处理Head注解
if (annotation instanceof Header) {
  Header header = (Header) annotation;
  String name = header.value(); //获取@head注解名称
    Converter<?, String> converter =
        retrofit.stringConverter(type, annotations);
    return new ParameterHandler.Header<>(name, converter); //
} 
// 处理Field参数注解
if (annotation instanceof Field) {
  if (!isFormEncoded) { //使用@Field注解必须在方法注解上声明@FormUrlEncoded注解
    throw parameterError(p, "@Field parameters can only be used with form encoding.");
  }
  Field field = (Field) annotation;
  String name = field.value(); //获取@Field注解名称
  boolean encoded = field.encoded();
  gotField = true;  //
    Converter<?, String> converter =  retrofit.stringConverter(type, annotations);
    return new ParameterHandler.Field<>(name, converter, encoded);
} 
//处理FieldMap参数注解
if (annotation instanceof FieldMap) {
  if (!isFormEncoded) { // //使用@Field注解必须在方法注解上声明@FormUrlEncoded注解
    throw parameterError(p, "@FieldMap parameters can only be used with form encoding.");
  }
 …….
  Converter<?, String> valueConverter =
      retrofit.stringConverter(valueType, annotations);
  gotField = true;
  return new ParameterHandler.FieldMap<>(valueConverter, ((FieldMap) annotation).encoded()); //创建ParameterHandler.FieldMap<>实例
}
//处理@part注解
else if (annotation instanceof Part) {
  if (!isMultipart) { //对于@part注解必须在方法上添加@Multipart注解
    throw parameterError(p, "@Part parameters can only be used with multipart encoding.");
  }
  Part part = (Part) annotation;
  gotPart = true;
  String partName = part.value(); //获取@Part注解名称
  Class<?> rawParameterType = Utils.getRawType(type);
  if (partName.isEmpty()) { //注解名称为空的情况
     
  } else { //当@part注解名称不为空
    Headers headers =
        Headers.of("Content-Disposition", "form-data; name=\"" + partName + "\"",
            "Content-Transfer-Encoding", part.encoding()); // 设置上传文件参数的头部信息
      return new ParameterHandler.Part<>(headers, converter); // 创建ParameterHandler.Part实例
} 
//处理@partMap注解
if (annotation instanceof PartMap) {
  if (!isMultipart) { // 添加@Multipart注解
    throw parameterError(p, "@PartMap parameters can only be used with multipart encoding.");
  }
  gotPart = true;
  Class<?> rawParameterType = Utils.getRawType(type);...
  Converter<?, RequestBody> valueConverter =
      retrofit.requestBodyConverter(valueType, annotations, methodAnnotations);
  PartMap partMap = (PartMap) annotation;
  return new ParameterHandler.PartMap<>(valueConverter, partMap.encoding());  
  //创建 ParameterHandler.PartMap<>实例
}
// 处理@Body注解
if (annotation instanceof Body) {
  if (isFormEncoded || isMultipart) { //@Multipart和@FormEncoded必须有一个
  }
  if (gotBody) { //已经设置了@Body
    throw parameterError(p, "Multiple @Body method annotations found.");
  }
  gotBody = true;
  return new ParameterHandler.Body<>(converter); //创建 ParameterHandler.Body<>实例
}
}

上面的代码虽然很多但逻辑很清晰,就是针对注解类型Url、Path、Query、QueryName、QueryMap、Header、HeaderMap、Field、FieldMap、Part、PartMap、Body分别处理参数,除了必要的判断外,根据不同注解创建ParameterHandler对应的子类,保存注解值和对应的类型转换器,具体的见注释

2.2、创建OkHttpCall
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
serviceMethod.callAdapter.adapt(okHttpCall)
  1. 获取转换的适配器Adapter,在上面知道执行了createCallAdapter()获取适配器,createCallAdapter()中根据方法的返回类型在已添加的adapter集合中查找
  2. 执行转换器的adapt()方法,已RxJavaAdapter为例最终返回的是一个Observable(),在Observable中封装了OkhttpCall(相求见后面分析)
  3. 经过上面的封装OKhttpCall已经转换成RxJava操作了,在RxJAva订阅之后会执行Observable的subscribeActual()方法,在subscribeActual()中执行了OkhttpCall的execute()
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
    Response<T> response = call.execute(); 
}
2.3、执行网络请求
@Override public Response<T> execute() throws IOException {
  okhttp3.Call call;
  synchronized (this) {
    executed = true;
    call = rawCall; //赋值rawCall,此时拿到的初始化时创建Okhttp的Call实例
    if (call == null) {
      try {
        call = rawCall = createRawCall(); //(1)
      } 
    }
  }
  if (canceled) { //取消请求
    call.cancel();
  }
  return parseResponse(call.execute()); //
}
private okhttp3.Call createRawCall() throws IOException {
  Request request = serviceMethod.toRequest(args); //
  okhttp3.Call call = serviceMethod.callFactory.newCall(request);  //
  return call;
}

除去外层的Adapter封装,请求最终调用OkHttpCall.execute()方法,execute()中的逻辑很清除,首先根据注解解析后的数据创建Okhttp中的Request对象那个,然后调用初始化时设置OkhttpClient创建Call实例

  • ServiceMethod.toRequest():创建Okhttp请求的Request实例,具体见注释
 Request toRequest(Object... args) throws IOException {
  //(1)封装保存所有请求信息,RequestBuilder内部创建了OKhttp中的Request.Builder requestBuilder;
  RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,contentType, hasBody, isFormEncoded, isMultipart);  
  ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers; //保存所有参数注解和参数注解信息的数组
  int argumentCount = args != null ? args.length : 0;
  for (int p = 0; p < argumentCount; p++) {
  handlers[p].apply(requestBuilder, args[p]); // (2)为每个参数和注解执行apply()方式(前面针对注解创建的ParameterHandler),将注解的参数注解和参数值进行拼接处理
  }
  return requestBuilder.build(); //(3)创建Okhttp的Request实例
}
  • ParameterHandler.apply()——此处根据解析参数注解时创建的ParameterHandler实例,调用对应的apply()方法,每个apply()都会将数据设置到最终的Request中
  1. @url——ParameterHandler.RelativeUrl.apply():保存请求的Url
//以Url注解为例
static final class RelativeUrl extends ParameterHandler<Object> {
  @Override void apply(RequestBuilder builder, Object value) {
    builder.setRelativeUrl(value); // 直接设置RequestBuilder请求的Url
  }
}
  1. @path——ParameterHandler.Path().apply():使用具体的参数值替换请求地址中的@Path注解
@Override void apply(RequestBuilder builder, T value) throws IOException {
  builder.addPathParam(name, valueConverter.convert(value), encoded);  //首先对参数值进行转换,然后在url中设置请求参数
}
void addPathParam(String name, String value, boolean encoded) {
  relativeUrl = relativeUrl.replace("{" + name + "}", canonicalizeForPath(value, encoded)); // 针对Path注解替换Url中的占位符字符串
}
  1. @query——ParameterHandler.Query<>:拼接处理最终的请求路径(http://****?key=value)
@Override void apply(RequestBuilder builder, T value) throws IOException {
  builder.addQueryParam(name, valueConverter.convert(value), encoded); // 对参数进行转换
}
void addQueryParam(String name, String value, boolean encoded) {
  if (relativeUrl != null) {
    urlBuilder = baseUrl.newBuilder(relativeUrl); //创建Okhttp中HttpUrl。Builder
    relativeUrl = null;
  }
  if (encoded) {
    urlBuilder.addEncodedQueryParameter(name, value); //加密设置,
  } else {
    urlBuilder.addQueryParameter(name, value); //直接添加参数和Value,最终都会将数据保存在encodedQueryNamesAndValues集合中
  }
}
  1. @head——ParameterHandler.Header<>:设置请求Request的Header信息
@Override void apply(RequestBuilder builder, T value) throws IOException {
  builder.addHeader(name, valueConverter.convert(value)); 
}
void addHeader(String name, String value) {
  if ("Content-Type".equalsIgnoreCase(name)) { //如果设置Content-Type暂时保存在contentType中,在创建Request中时设置
    MediaType type = MediaType.parse(value);
    contentType = type; //保存ContentType
  } else {
    requestBuilder.addHeader(name, value); //直接调用Okhttp中的Request。Builder设置头部信息
  }
}
  1. @Field——ParameterHandler.Field<>:为Post请求设置请求参数
@Override void apply(RequestBuilder builder, T value) throws IOException {
  builder.addFormField(name, valueConverter.convert(value), encoded);
}
void addFormField(String name, String value, boolean encoded) {
  if (encoded) {
    formBuilder.addEncoded(name, value); //调用FormBody.Builder添加参数值
  } else {
    formBuilder.add(name, value); 
  }
}
  1. @FieldMap——ParameterHandler.FieldMap<>:为Post请求设置参数集合
@Override void apply(RequestBuilder builder, Map<String, T> value) throws IOException {
  for (Map.Entry<String, T> entry : value.entrySet()) {
    String entryKey = entry.getKey(); //获取Map的Key
    T entryValue = entry.getValue(); //获取Map的Value
    builder.addFormField(entryKey, valueConverter.convert(entryValue), encoded); //便利整个参数Map依次添加参数值
  }
}
  1. @part——ParameterHandler.Part<>:根据参数信息,设置请求MultipartBody的参数
@Override void apply(RequestBuilder builder, T value) {
  RequestBody body;
  body = converter.convert(value); //  转为RequestBody实例
  builder.addPart(headers, body);
void addPart(Headers headers, RequestBody body) {
  multipartBuilder.addPart(headers, body); //MultipartBody.Builder添加参数
}
  1. @partMap——ParameterHandler.PartMap<>:处理PartMap
@Override void apply(RequestBuilder builder, Map<String, T> value) throws IOException {
  for (Map.Entry<String, T> entry : value.entrySet()) {
    String entryKey = entry.getKey(); //获取Map的key
    T entryValue = entry.getValue(); //获取Map的Value
    //为每个文件传输设置头部信息
    Headers headers = Headers.of(
        "Content-Disposition", "form-data; name=\"" + entryKey + "\"",
        "Content-Transfer-Encoding", transferEncoding);
    builder.addPart(headers, valueConverter.convert(entryValue));
  }
}
void addPart(Headers headers, RequestBody body) {
  multipartBuilder.addPart(headers, body);
}
  1. @Body——ParameterHandler.Body<>:直接设置请求RequestBody
@Override void apply(RequestBuilder builder, T value) {
  RequestBody body;
  try {
    body = converter.convert(value);
  builder.setBody(body); 
}
void setBody(RequestBody body) {
  this.body = body; //设置RequestBody
}
  • RequestBuilder.build()——创建OkHttp请求的Request实例
public Request build() {
  HttpUrl url;
  HttpUrl.Builder urlBuilder = this.urlBuilder;
  if (urlBuilder != null) {
    url = urlBuilder.build();
  } else {
    url = baseUrl.resolve(relativeUrl);  //设置请求的Url
  }
  RequestBody body = this.body;  //设置请求Body
  
  RequestBody body = this.body;
  if (body == null) {
  if (formBuilder != null) {
    body = formBuilder.build();
  } else if (multipartBuilder != null) {
    body = multipartBuilder.build();
  } 
 }
  MediaType contentType = this.contentType;
  if (contentType != null) {
    if (body != null) {
      body = new ContentTypeOverridingRequestBody(body, contentType);
    } else {
      requestBuilder.addHeader("Content-Type", contentType.toString());  //设置请求头部信息
    }
  }
  return requestBuilder      //利用Okhttp的RequestBuilder创建请求的Request
      .url(url)
      .method(method, body)
      .build();
}
  • 创建RealCall
okhttp3.Call call = serviceMethod.callFactory.newCall(request);  //调用初始化时设置OkhttpClient创建Call实例
  • 执行——真正执行call.execute()
call.execute()

3、解析返回的Response

parseResponse(call.execute());
  • call.execute()执行后获取Okhttp返回的Response,根据状态码确定请求结果
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
  ResponseBody rawBody = rawResponse.body(); //获取请求返回Body
  rawResponse = rawResponse.newBuilder()
  //创建ExceptionCatchingRequestBody实例
  ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);   
  try {
    T body = serviceMethod.toResponse(catchingBody); // (1)调用ServiceMethod.toResponse()转化响应结果(Gson在此执行映射对象)
    return Response.success(body, rawResponse); //(2)返回请求成功,参数:转化后的对象、原来的Response
  } catch (RuntimeException e) {
    catchingBody.throwIfCaught();
    throw e;
  }
}

首先获取ResponseBody,然后调用ServiceMethod.toResponse()转化响应结果(Gson在此执行映射对象),最后返回Reponse

  • 调用ServiceMethod.toResponse()根据设置的转换器,转换Response返回的结果,这里获取的responseConverter对象就是在ServiceMethod中获取(参考上面获取RxJavaAdapter的过程),最终执行的是GsonConverterFactory.convert()
R toResponse(ResponseBody body) throws IOException {
  return responseConverter.convert(body); //调用设置的对结果的转换器转换Response
}
ServiceMethod build(){ // 此处的responseConverter
responseConverter = createResponseConverter();
}
  • GsonConverterFactory.convert():Json转换为对象T
@Override public T convert(ResponseBody value) throws IOException {
  JsonReader jsonReader = gson.newJsonReader(value.charStream()); // 获取JsonReader
  try {
    return adapter.read(jsonReader); //读取JsonReader转换为对象
  } finally {
    value.close();
  }
}
  • Response<>():将转换后的结果保存在Response中并返回
public static <T> Response<T> success(T body, okhttp3.Response rawResponse) {
 。。。。。。 
  return new Response<>(rawResponse, body, null); // (1)封装转换后的Object和原始的Response
}
* addConverterFactory():为对象的序列化和反序列化添加转换器工厂,上面的converterFactories也是此处添加
public Builder addConverterFactory(Converter.Factory factory) {
  converterFactories.add(checkNotNull(factory, "factory == null"));//保存添加的Converter.Factory
  return this;
}

4、转换请求方式(以RxJava2CallAdapterFactory为例)

@FormUrlEncoded
@POST("user/register/")
fun register( @Field("repassword") repassword: String): Call<ArticleBean> //返回Call实例
  • callAdapter.adapt(okHttpCall):在create()实例化接口对象时,调用AdapterFactory.adapt()转换OkhttpCall,系统默认使用DefaultCallAdapterFactory,在DefaultCallAdapterFactory中直接返回Call,所以Retrofit注解的方法默认返回Call
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();
  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }
      @Override public Call<Object> adapt(Call<Object> call) {
        return call;  //默认直接返回RealCall实例
      }
    };
  }
}
  • 根据数据的返回类型获取转换适配器,执行adapt()转换OkhttpCall实例
serviceMethod.callAdapter.adapt(okHttpCall);
//最终执行nextCallAdapter()
public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
  int start = adapterFactories.indexOf(skipPast) + 1;
  for (int i = start, count = adapterFactories.size(); i < count; i++) { //获取设置的AdapterFcatory
    CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this); 
    if (adapter != null) {
      return adapter;
    }
  }
}
  • addCallAdapterFactory():在创建Retrofit实例时添加Call转换器工厂,所有的转换工厂会保存在adapterFactories,上面就是从adapterFactories查找适配器
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
  //将添加的Adapter.Factory保存在 adapterFactories集合中
  adapterFactories.add(checkNotNull(factory, "factory == null"));
  return this;
}
  • RxJava2CallAdapter
@Override public Object adapt(Call<R> call) { //传入的OkhttpCall
  Observable<Response<R>> responseObservable = isAsync
      ? new CallEnqueueObservable<>(call)
      : new CallExecuteObservable<>(call); 
  Observable<?> observable;
  if (isResult) {
    observable = new ResultObservable<>(responseObservable);
  } else if (isBody) {
    observable = new BodyObservable<>(responseObservable); //对于RxJava此处创建的是BodyObservable
  } else {
    observable = responseObservable;
  }
  return observable;
}
//执行被观察者
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
  Call<T> call = originalCall.clone(); // (1)Copy一份OKhttpCall
  try {
    Response<T> response = call.execute(); // (2)执行OKhttpCall完成网络请求和数据转换
    if (!call.isCanceled()) {
      observer.onNext(response); // (3)发送数据,发送的是封装转化对象和Response的对象
    }
  } 
}

在使用Retrofit时一般设置RxJava2CallAdapter,将创建执行的Call转换为Observable实例,这里直接看adapt()首先根据同步或异步选择相应的被观察者,在被观察者执行时会执行Observable的subscribeActual(),在subscribeActual中执行OKhttpCall完成网络请求和数据转换,然后执行onNext()发送数据

  • BodyObservable:获取Response中的Body作为最终的对象发送
BodyObservable(Observable<Response<T>> upstream) {
  this.upstream = upstream; // 构造函数中保存传入的Observable实例
}
@Override protected void subscribeActual(Observer<? super T> observer) {
  upstream.subscribe(new BodyObserver<T>(observer)); //调用保存实力的方法去获取数据
}
Override public void onNext(Response<R> response) {
  if (response.isSuccessful()) {
    observer.onNext(response.body()); // 只发送请求的Body即转换后的对象
  }
}

到这里Retrofit的源码分析结束了,总结一下Retrofit的完整执行流程:

  1. 首先根据需要创建并配置Retrofit的实例,此时需要设置相应的请求适配器和结果转换器
  2. 在接口方法中配置retrofit的方法、方法注解、参数及参数注解
  3. 在调用Retrofit.create()实例化API接口时,为Retrofit注解设置动态代理,接口中所有方法都会被动态代理拦截
  4. 在调用接口方法时,回调执行动态代理中的InvocationHandler(),解析处理方法注解和参数注解的信息,保存在ServiceMethod实例中,并缓存ServiceMethod
  5. 创建OkHttpCall实例,保存ServiceMethod实例 和 传入的参数数组
  6. 调用Retrofit配置的CallAdapter.Factory中的CallAdapter.adapt()转换OkHttpCall实例,在转换后的对象中保存并引用OkhttpCall
  7. 执行转换实例会间接调用OkhttpCall的execute()执行方法时,根据保存ServiceMethod实例和传入参数解析并创建Okhttp中的Request实例
  8. 使用传入的OkhttpClient和创建的Request创建真实的RealCall
  9. 执行RealCall网络请求解析返回的结果,根据结果创建并返回Response的实例
  10. 调用设置的结果转换器,转换并发送相应的数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值