【笔记】开源框架 - Retrofit实现原理

从Retrofit的使用入手分析,首先展示一个Retrofit使用demo:

1 定义一个请求接口

public interface LocalTestNetworkApi {
    @GET("users/{user}")
    Call<UserInfo> getLocalUserInfo(@Path("user") int userId);
}

2 使用Retrofit做请求处理

2.1 创建及初始化Retrofit,至少需要传入url,支持自定义

2.2 retrofit create创建出接口实例对象

2.3 使用Api对象调用网络请求方法

2.4 结果处理

Retrofit retrofit = new Retrofit.Builder()
                       .client(new OkHttpClient())
                       .baseUrl(BASE_URL)
                       .build();
LocalTestNetworkApi testNetworkApi = retrofit.create(LocalTestNetworkApi.class);
retrofit2.Call<UserInfo> call = testNetworkApi.getLocalUserInfo(2);
call.enqueue(new retrofit2.Callback<UserInfo>() {
    @Override
    public void onResponse(retrofit2.Call<UserInfo> call, retrofit2.Response<UserInfo> response) {
        // Doing something...
    }

    @Override
    public void onFailure(retrofit2.Call<UserInfo> call, Throwable t) {
        // Doing something...
    }
});

分析实现原理

一、初始化

1 初始化及创建Retrofit对象

baseUrl 传入url,会转化成Url对象

callFactory 可选,如果没有设置,build时默认new OkHttpClient

callbackExecutor 可选,如果没有设置,build时默认添加:(实际默认值是null)

addCallAdapterFactory 可选,除使用者添加的,build时还会另外添加默认factory

addConverterFactory 可选,除使用者添加的,build时还会另外添加 BuiltInConverters

public Retrofit build() {
  // 禁止空url
  if (baseUrl == null) {
	throw new IllegalStateException("Base URL required.");
  }
  // 如果使用者没有设置,默认为 OkHttpClient
  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
	callFactory = new OkHttpClient();
  }
  // 如果使用者没有设置,设置默认值(实际是null)
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
	callbackExecutor = platform.defaultCallbackExecutor();
  }

  // Make a defensive copy of the adapters and add the default Call adapter.
  // 使用者设置的factory
  List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  // 除使用者设置的factory外另添加platform.defaultCallAdapterFactory
  callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

  List<Converter.Factory> converterFactories =
	  new ArrayList<>(1 + this.converterFactories.size());

  // 先添加BuiltInConverters
  converterFactories.add(new BuiltInConverters());
  // 再添加使用者设置的converterFactory
  converterFactories.addAll(this.converterFactories);

  return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
	  unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}

2 创建网络请求API接口实例

实际就是创建了一个请求接口的动态代理类

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, @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);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.adapt(okHttpCall);
          }
        });
}

3 调用请求网络方法

实际上执行动态代理invoke,这里看一下invoke中做了什么:

3.1 创建ServiceMethod

由于此方法中涉及复杂操作,因此首次调用创建后会缓存起来。ServiceMethod.Builder.build

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);
  }
  // 合法性检查 ...

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

  // 合法性检查 ...
  return new ServiceMethod<>(this);
}

3.1.1 创建CallAdapter

private CallAdapter<T, R> createCallAdapter() {
  // 返回值类型
  Type returnType = method.getGenericReturnType();
  if (Utils.hasUnresolvableType(returnType)) {
    throw methodError(
        "Method return type must not include a type variable or wildcard: %s", returnType);
  }
  if (returnType == void.class) {
    throw methodError("Service methods cannot return void.");
  }
  Annotation[] annotations = method.getAnnotations();
  try {
    //noinspection unchecked
    return (CallAdapter<T, R>) 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);
  }
}
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
}

public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      // 遍历所有的CallAdapter,根据返回值类型找出适配的CallAdapter
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
        .append(returnType)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
}

    根据网络请求方法返回值类型遍历匹配符合的CallAdapter,框架提供了三种CallAdapter,对应如下三个Factory,从代码可以看出会判断返回值类型不合法返回null,命中的返回自己的CallAdapter:

RxJava2CallAdapterFactory:

  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    Class<?> rawType = getRawType(returnType);

    if (rawType == Completable.class) {
      // Completable is not parameterized (which is what the rest of this method deals with) so it
      // can only be created with a single configuration.
      return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
          false, true);
    }

    boolean isFlowable = rawType == Flowable.class;
    boolean isSingle = rawType == Single.class;
    boolean isMaybe = rawType == Maybe.class;
    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
      return null;
    }

    boolean isResult = false;
    boolean isBody = false;
    Type responseType;
    if (!(returnType instanceof ParameterizedType)) {
      String name = isFlowable ? "Flowable"
          : isSingle ? "Single"
          : isMaybe ? "Maybe" : "Observable";
      throw new IllegalStateException(name + " return type must be parameterized"
          + " as " + name + "<Foo> or " + name + "<? extends Foo>");
    }

    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
    Class<?> rawObservableType = getRawType(observableType);
    if (rawObservableType == Response.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Response must be parameterized"
            + " as Response<Foo> or Response<? extends Foo>");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    } else if (rawObservableType == Result.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Result must be parameterized"
            + " as Result<Foo> or Result<? extends Foo>");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
      isResult = true;
    } else {
      responseType = observableType;
      isBody = true;
    }

    return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  }

ExecutorCallAdapterFactory: 

  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<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

DefaultCallAdapterFactory:

  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<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return call;
      }
    };
  }

 3.1.2 创建ResponseConverter

  private Converter<ResponseBody, T> createResponseConverter() {
      Annotation[] annotations = method.getAnnotations();
      try {
        return retrofit.responseBodyConverter(responseType, annotations);
      } catch (RuntimeException e) {
        throw methodError(e, "Unable to create converter for %s", responseType);
      }
  }

  public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
  }

  public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
      @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
    checkNotNull(type, "type == null");
    checkNotNull(annotations, "annotations == null");

    int start = converterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      // 遍历寻找匹配的converter
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        return (Converter<ResponseBody, T>) converter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ")
        .append(type)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }

    类似前面CallAdapter的创建,这里根据responseType遍历所有ResponseConverter找到匹配的Converter。

3.1.3 通过反射解析使用者定义的API接口,通过注解信息得到完整的请求信息。

3.2 创建返回值返回给使用者。这里CallAdapter是根据返回值类型匹配到的对应的CallAdapter,因此返回值类型是确定的。

3.2.1 RxJava2CallAdapter:

 public Object adapt(Call<R> call) {
    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);
    } else {
      observable = responseObservable;
    }

    if (scheduler != null) {
      observable = observable.subscribeOn(scheduler);
    }

    if (isFlowable) {
      return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
      return observable.singleOrError();
    }
    if (isMaybe) {
      return observable.singleElement();
    }
    if (isCompletable) {
      return observable.ignoreElements();
    }
    return observable;
  }

3.2.2 ExecutorCallAdapterFactory->CallAdapter:

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

      @Override public Call<Object> adapt(Call<Object> call) {
        // callbackExecutor是使用者通过callbackExecutor传入的
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };

3.2.3 DefaultCallAdapterFactory->CallAdapter:

回看前面动态代理invoke的代码,这个call是new OkHttpCall传入的,直接返回给使用者。

    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }
      // 这个call回看前面代码,是动态代理invoke时创建的new OkHttpCall传入,直接返回给使用者
      @Override public Call<Object> adapt(Call<Object> call) {
        return call;
      }
    };

不管使用什么CallAdapter,最终都是操作OkHttpCall实现请求的,OkHttpCall内封装OkHttp进行网络请求。

完成请求后parseResponse解析结果,使用converter解析。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值