美文网首页
retrofit源码分析

retrofit源码分析

作者: 冬冬269 | 来源:发表于2018-10-24 15:09 被阅读0次
    //分析1
     Retrofit build = new Retrofit.Builder().baseUrl("xxxxxxx")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
    
    
    
    //分析2
            ServiceDemo serviceDemo = build.create(ServiceDemo.class);
    
    //分析3
            Call string = serviceDemo.getString("111", "222");
    
    //分析4
            string.enqueue(new Callback() {
                @Override
                public void onResponse(Call call, Response response) {
    
                }
    
                @Override
                public void onFailure(Call call, Throwable t) {
    
                }
            });
    

    分析1

    创建retrofit 是使用建造者模式建造者模式

    可以设置的参数很多,列举几个。

    
    
    角色 作用 备注
    converterFactory 格式转换工厂 支持gson json xml
    callAdapterFactory 网络请求适配器工厂 ExecutorCalladapter(默认)、RxJava2CallAdapterFactory
    client 网络请求所使用的具体okhttp对象 可以用来设置超时时间等等一系列okhttp的属性
    callBackExecutor 用于做线程切换

    分析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();
    
              @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);
                }
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
      }
    

    可以看到这里使用的是java的动态代理。这里是retrofit的核心。通过动态代理,可以轻易拿到Method,进而读取Method的注解。

    动态代理,在运行时动态的创建代理类,这个类就是Proxy类,调用Proxy类的方法都会调用InvacationHandler的invoke方法。

    先判断这个方法的类,如果是object,直接调用。
    Platform:对不同的平台,有不同的行为。
    ServiceMethod:把接口中的方法适配为符合http的call

    分析3

    实际就会调用

    @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);
                }
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
    

    我们要详细分析

    ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
    
    
      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;
      }
    

    key = method,value = ServiceMethod。用来存储的是CorrentHashMap。我们要进而认识一下什么是ServiceMethod,简而言之就是解析Method,存储网络请求的数据。什么是okHttpCall。

    ParameterHandler 方法参数处理器

     public ServiceMethod build() {
          callAdapter = createCallAdapter();
          responseType = callAdapter.responseType();
          if (responseType == Response.class || responseType == okhttp3.Response.class) {
            throw methodError("'"
                + Utils.getRawType(responseType).getName()
                + "' is not a valid response body type. Did you mean ResponseBody?");
          }
          responseConverter = createResponseConverter();
    
    
    CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
    
    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));
    
     static class Android extends Platform {
        @Override public Executor defaultCallbackExecutor() {
          return new MainThreadExecutor();
        }
    
        @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          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);
          }
        }
      }
    
    final 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);
          }
        };
      }
    
      static final class ExecutorCallbackCall<T> implements Call<T> {
        final Executor callbackExecutor;
        final Call<T> delegate;
    
        ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
          this.callbackExecutor = callbackExecutor;
          this.delegate = delegate;
        }
    
        @Override public void enqueue(final Callback<T> callback) {
          checkNotNull(callback, "callback == null");
    
          delegate.enqueue(new Callback<T>() {
            @Override public void onResponse(Call<T> call, final Response<T> response) {
              callbackExecutor.execute(new Runnable() {
                @Override public void run() {
                  if (delegate.isCanceled()) {
                    // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                    callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                  } else {
                    callback.onResponse(ExecutorCallbackCall.this, response);
                  }
                }
              });
            }
    
            @Override public void onFailure(Call<T> call, final Throwable t) {
              callbackExecutor.execute(new Runnable() {
                @Override public void run() {
                  callback.onFailure(ExecutorCallbackCall.this, t);
                }
              });
            }
          });
        }
    
        @Override public boolean isExecuted() {
          return delegate.isExecuted();
        }
    
        @Override public Response<T> execute() throws IOException {
          return delegate.execute();
        }
    
        @Override public void cancel() {
          delegate.cancel();
        }
    
        @Override public boolean isCanceled() {
          return delegate.isCanceled();
        }
    
        @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
        @Override public Call<T> clone() {
          return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
        }
    
        @Override public Request request() {
          return delegate.request();
        }
      }
    }
    
    
    ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
    

    okhttpcall:真正执行okhttp的call。创建ServiceMethod时创建了一个CallAdapter的实例。CallAdapter是一个接口。在ExecutorCallAdapterFactory中创建了这个实例。ExecutorCallAdapterFactory是在platfrom中创建的,创建时传入了一个MainThreadExecutor用来做线程切换。CallAdapter.adapt时,返回了一个okhttpcall的代理对象,这个对象中包括了一个MainThreadExecutor 和okhttpcall。代理的作用是做线程的切换。

    看完源码:发现了retrofit的核心是动态代理。底层使用okhttp。动态代理的好处是可以轻易拿到Method,我们通过注解去设置和配置的数据,通过读取Method读取每个方法的注解,参数的注解。去配置网络请求参数,然后封装成okttpcall去做网络请求。

    读到这里,retrofit的机制大概已经明白了。那么okhttp又做了什么。还要读okhttp的源码。

    相关文章

      网友评论

          本文标题:retrofit源码分析

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