美文网首页android
retrofit源码解析--网络请求接口解析

retrofit源码解析--网络请求接口解析

作者: 二妹是只猫 | 来源:发表于2019-03-19 14:09 被阅读23次
Retrofit.png

retrofit的精华就在于使用注解将网络请求抽象成接口以供使用,本文就来分析它是如何实现的。

public interface retrofitService {
       @GET("try")
       public Call getCall();
}
 Retrofit retrofit = new Retrofit.Builder()
         .baseUrl("baseurl")
         .addConverterFactory(GsonConverterFactory.create())
         .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
         .build();
 retrofitService retrofitService = retrofit.create(retrofitService.class);

retrofit.create(retrofitService.class):

public <T> T create(final Class<T> service) {
1  Utils.validateServiceInterface(service);
2  if (validateEagerly) {
    eagerlyValidateMethods(service);
  }
3  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);
          }
4         ServiceMethod<Object, Object> serviceMethod =  (ServiceMethod<Object, Object>) loadServiceMethod(method);
5         OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
6         return serviceMethod.callAdapter.adapt(okHttpCall);
        }
      });
}

private void eagerlyValidateMethods(Class<?> service) {
 Platform platform = Platform.get();
  for (Method method : service.getDeclaredMethods()) {
    if (!platform.isDefaultMethod(method)) {
      loadServiceMethod(method);
    }
  }
}

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;
}
  • 1.判断接口是否符合条件Utils.validateServiceInterface:
 static <T> void validateServiceInterface(Class<T> service) {
    if (!service.isInterface()) {
      throw new IllegalArgumentException("API declarations must be interfaces.");
    }
    // Prevent API interfaces from extending other interfaces. This not only avoids a bug in
    // Android (http://b.android.com/58753) but it forces composition of API declarations which is
    // the recommended pattern.
    if (service.getInterfaces().length > 0) {
      throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
    }
  }
  • 2.validateEagerly这个标记位在retrofit源码解析--基本使用和关键成员变量介绍中有介绍,它的作用是来判断是否立即解析接口中的方法,如今就看看它具体是怎么做的:
    eagerlyValidateMethods
    获取到平台(Platform),然后遍历接口中的方法,调用loadServiceMethod
    loadServiceMethod
    在loadServiceMethod中通过serviceMethodCache来存储转换为ServiceMethod类型的Method
    serviceMethodCache这个变量在retrofit源码解析--基本使用和关键成员变量介绍中也有介绍,它的作用是存储接口中的方法,这里就是它的运用。

  • 3.通过动态代理将接口转换成适配器指定的类型。其中4、5、6这几行代码是整个retrofit的重点,将进行重点解析



    1. loadServiceMethod()在标记2中已经介绍过,这里主要介绍ServiceMethod
result = new ServiceMethod.Builder<>(this, method).build();

这里又是通过建造者模式来创建了ServiceMethod,在retrofit源码解析--ServiceMethod
有具体分析

相关文章

网友评论

    本文标题:retrofit源码解析--网络请求接口解析

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