retrofit2源码分析

Retrofit官网 http://square.github.io/retrofit/

分析源码基本上都是从demo开始的

首先知道如何调用官网首页给的例子

1.先定义一个接口

首页api声明中明确指出每个接口方法必须包含http请求方法注解GETPOSTPUTDELETE, and HEAD,并且可以加入请求参数

具体 @Path @QueryMap @FormUrlEncoded  @Multipart 等格式写法请参考官方文档

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

2.创建根据接口创建 retrofit实现

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);
3.进行网络请求

扫描二维码关注公众号,回复: 5941698 查看本文章
Call<List<Repo>> repos = service.listRepos("octocat");

到此请求完成


接下来具体分析代码流程

首先定义接口 GitHubService 抽象要完成的数据请求

创建retrofit实例是通过build完成的

public Builder() {
      this(Platform.get());
    }

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

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }
根据是android还是java平台返回具体实现

static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

Android代码包含一个CallAdapter.Factory和MainThreadExecutor
MainThreadExecutor中只有一个handler.post(runnable)

CallAdapter.Factory是根据返回值类型创建返回值

然后是执行baseUrl("https://api.github.com/")方法

/**
     * Set the API base URL.
     *
     * @see #baseUrl(HttpUrl)
     */
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }

HttpUrl(Builder builder) {
    this.scheme = builder.scheme;
    this.username = percentDecode(builder.encodedUsername, false);
    this.password = percentDecode(builder.encodedPassword, false);
    this.host = builder.host;
    this.port = builder.effectivePort();
    this.pathSegments = percentDecode(builder.encodedPathSegments, false);
    this.queryNamesAndValues = builder.encodedQueryNamesAndValues != null
        ? percentDecode(builder.encodedQueryNamesAndValues, true)
        : null;
    this.fragment = builder.encodedFragment != null
        ? percentDecode(builder.encodedFragment, false)
        : null;
    this.url = builder.toString();
  }
创建了httpurl类封装了请求地址以及端口号以及参数编解码信息等信息

然后执行build()方法创建Retrofit实例

/**
     * Create the {@link Retrofit} instance using the configured values.
     * <p>
     * Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
     * OkHttpClient} will be created and used.
     */
    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

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

build方法中首先创建了请求网络实例 callFactory = new OkHttpClient();

然后根据平台类型设置callbackExecutor类即android中的handler

然后将平台处理CallAdapter.Factory放到retrofit中,然后创建出retrofit实例

到现在并没有看到GitHubService的具体实现代码

下面进入retrofit.create(GitHubService.class);方法

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, 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.callAdapter.adapt(okHttpCall);
          }
        });
  }
首先通过 Utils. validateServiceInterface 判断参数是否是接口,并且接口不能继承其它接口

然后根据接口系统直接创建代理类返回

最后调用接口方法执行具体操作


因为代理类重写了

@Override public Object invoke(Object proxy, Method method, Object[] args)
方法所有方法执行都会进入此方法内进行具体处理
 
 
ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

首先执行的是此方法会将方法请求进行缓存以防每次都新建
从代码可以看出会根据method创建出ServiceMethod,
ServiceMethod中包涵接口方法中的返回参数,方法注解以及参数中的注解处理,返回值处理等信息

然后根据ServiceMethod创建new OkHttpCall<>(serviceMethod, args);

最后调用serviceMethod.callAdapter.adapt(okHttpCall)

真正执行的代码为Android平台下的ExecutorCallAdapterFactory

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

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }
serviceMethod. callAdapter .adapt(okHttpCall)调用了此处的 adapt(Call<Object> call) 方法,

ExecutorCallbackCall与handler进行交互处理进而与返回值进行取消网落操作处理

具体网络请求代码在okHttp中请自己查看

关于Converter.Factory okHttp代码具体细节代码未涉及
到此关于retrofit的代码到此结束本





猜你喜欢

转载自blog.csdn.net/H291850336/article/details/66972229