美文网首页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