美文网首页程序员
retrofit源码流程

retrofit源码流程

作者: 小小爱笑 | 来源:发表于2018-10-23 12:49 被阅读0次

    前言

    retrofit 是一个类型安全的http 客户端库。是对okhttp的封装。

    使用:

     * Retrofit retrofit = new Retrofit.Builder()
     *     .baseUrl("https://api.example.com/")
     *     .addConverterFactory(GsonConverterFactory.create())
     *     .build();
     *
     * MyApi api = retrofit.create(MyApi.class);
     * Response user = api.getUser().execute();
    

    1.retrofit创建:
    retrofit主要包括:

    • callFactory --OkHttpClient

    • baseUrl --传入的域名

    • converterFactories
      转换器的工厂列表, Converter.Factory 接口实现, 抽象工厂模式。
      包括responseBodyConverter,
      requestBodyConverter, RequestFactory解析@body标签时 使用。
      stringConverter RequestFactory解析@query标签时 使用。
      默认,加入BuiltInConverters。

    • callAdapterFactories

    默认时 接口返回Call<ResponseBody>类型。
    CallAdpater用于将Call<?>适配到其他类型。
    注 : ResponseBody由Converter负责转换。
    默认时 java平台加入DefaultCallAdapterFactory
    android 加入ExecutorCallAdapterFactory:不改变返回值类型,只做线程切换。

    2.创建接口代理实现:

    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();
              private final Object[] emptyArgs = new Object[0];
    
              @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);
                }
                return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
              }
            });
      }
    

    生成的代理 调用时,相当于调用
    loadServiceMethod(method).invoke()
    每个接口方法对应于一个ServiceMethod对象。

    abstract class ServiceMethod<T> {
      static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    
        Type returnType = method.getGenericReturnType();
        if (Utils.hasUnresolvableType(returnType)) {
          throw methodError(method,
              "Method return type must not include a type variable or wildcard: %s", returnType);
        }
        if (returnType == void.class) {
          throw methodError(method, "Service methods cannot return void.");
        }
    
        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
      }
    
      abstract T invoke(Object[] args);
    }
    
    static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
          Retrofit retrofit, Method method, RequestFactory requestFactory) {
        CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
        Type responseType = callAdapter.responseType();
        if (responseType == Response.class || responseType == okhttp3.Response.class) {
          throw methodError(method, "'"
              + Utils.getRawType(responseType).getName()
              + "' is not a valid response body type. Did you mean ResponseBody?");
        }
        if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
          throw methodError(method, "HEAD method must use Void as response type.");
        }
    
        Converter<ResponseBody, ResponseT> responseConverter =
            createResponseConverter(retrofit, method, responseType);
    
        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
      }
    

    ServiceMethod对象 根据注解创建。
    3.调用接口:
    HttpServiceMethod.java

    @Override ReturnT invoke(Object[] args) {
        return callAdapter.adapt(
            new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
      }
    

    生成OkHttpCall对象,并通过callAdapter适配到特定类型。


    参考:
    https://square.github.io/retrofit/

    相关文章

      网友评论

        本文标题:retrofit源码流程

        本文链接:https://www.haomeiwen.com/subject/zoqgzftx.html