源码角度---Retrofit之create()分析

最近在没事,就想看看Retrofit的源码,梳理一下这么主流的网络框架是怎么执行的。直到我点进去后,发现里面大量使用了一些特别好的设计模式,所以,我想摘录下来,巩固一下这些知识点。

Android中的网络注解框架Retrofit内部实现其实就是应用了动态代理技术,通常我们定义的网络接口是这样的:

public interface ApiStore {

    // 员工登录
    @FormUrlEncoded
    @POST("/resource/d/member/login")
    Observable<BaseResponse<LoginResult>> login(@FieldMap Map<String, String> params);

    // 退出登录
    @FormUrlEncoded
    @POST("/resource/d/member/signOut")
    Observable<BaseResponse<LogOutResult>> logout(@FieldMap Map<String, String> params);
    
    //....
}

创建Retrofit:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://ww.xxx.com/")
    .build();
ApiStore service = retrofit.create(ApiStore.class);

当我们点进去create方法,这句代码其实就是创建了一个代理类Proxy

  @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
  public <T> T create(final Class<T> service) {
     //检查传入的类为接口并且无继承
    Utils.validateServiceInterface(service); 
    if (validateEagerly) {
      //判断是否需要提前验证
      //需要注意的,如果不是提前验证则进行动态解析对应方法
      eagerlyValidateMethods(service);
    }

   //重点是这里
   //首先返回一个利用代理实现的GitHub对象 
    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);
          }
        });
  }

上面代码中retrofit就是通过Proxy.newProxrInstance()Service.getClassLoader(),new Class<?>[]{service},new invocationHandler())的方式创建的一个代理类。

invoke中的代码就是当网络接口被调用的时候需要做的处理。在这个方法里面,首先根据接口定义的方法,去生成一个ServiceMethod对象。在这个ServiceMethod对象中会反射接口中定义的注解,解析出具体的网络请求方式。


  ServiceMethod<?> loadServiceMethod(Method method) {
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);  //以Method为键将该对象存入LinkedHashMap集合中
      }
    }
    return result;
  }

最后,loadServiceMethod(method).invoke(args != null ? args : emptyArgs)方法中的invoke方法中中,具体是实现了创建OkHttpCall对象。便于进行真正的网络请求(OKHttp)

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

以上这里,我们就已经宏观的了解到Retrofit是怎样通过代理,解析接口注解,最后调用OKHttp去实现网络请求的一个流程。

猜你喜欢

转载自blog.csdn.net/weixin_33831673/article/details/87048869