Retrofit 分析

2019-05-29  本文已影响0人  水清波

先上一个RetrofitHelper 使用kotlin的默认单例模式

object RetrofitHelper {
    private var mOkHttpClient: OkHttpClient? = null
    fun getGankApiService() = createApi(GankApi::class.java, "http://gank.io/")
    private fun <T> createApi(clazz: Class<T>, baseUrl: String): T {
        if (mOkHttpClient == null)
            initOkHttpClient()
        val retrofit = Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(mOkHttpClient!!)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        return retrofit.create(clazz)
    }

    private fun initOkHttpClient() {
        val httpLoggingInterceptor = HttpLoggingInterceptor()
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        if (mOkHttpClient == null) {
            synchronized(RetrofitHelper::class.java) {
                if (mOkHttpClient == null) {
                    //val cache = Cache(File(.getCacheDir(), "HttpCache"), 1024 * 1024 * 1)
                    mOkHttpClient = OkHttpClient.Builder()
                        //.cache(cache)
                        .addInterceptor(httpLoggingInterceptor)
                        .retryOnConnectionFailure(true)
                        .connectTimeout(30, TimeUnit.SECONDS)
                        .writeTimeout(20, TimeUnit.SECONDS)
                        .readTimeout(20, TimeUnit.SECONDS)
                        .build()
                }
            }
        }
    }
}

Retrofit.java中create方法

 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.adapt(okHttpCall);
          }
        });
  }

create 先先检查service,不是接口报错,接口有继承也报错
返回 动态代理代理接口,加入回掉
1.确定平台,安卓平台
2.如果是object类的方法直接调用
3.平台默认方法(不支持,一直返回false)
4.新建ServiceMethod,把一个接口转换到一个httpcall

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;
  }

5.ServiceMethod的build方法 新建callAdapter,到retrofit的callAdapterFactories抽象工厂缓存里用get生产实例
6.callAdapter的返回类型才是最终的返回类型
7.生成responseConverter,类似上面也是抽象工厂从retrofit缓存生产转换器
8.后续 把方法注解路径等都抽出来转换到内置属性
9.OkHttpCall用ServiceMethod来构造,由okhttpclient生产
10.OkHttpCall是okhttp3.Call的泛型版本,okhttp3.Call嵌套调用OkHttpCall的onresponse和onFailure;返回还会被parseResponse做成功转换
11.默认calladapter情况下serviceMethod.adapt(okHttpCall) 返回okHttpCall

addCallAdapterFactory(RxJava2CallAdapterFactory.create())

callAdapterFactories抽象工厂模式 get生产实例
nextCallAdapter里获得callAdapterFactories中第一个的CallAdapter,先自定义后默认
RxJava2CallAdapter的adapt新建Observable

OKHTTP3

newcall新建realcall代表一次请求,
enqueue异步任务的时候交给clinet的Dispatcher的enqueue
enqueue的是一个runnable (子类实现AsyncCall)交给线程池
异步任务使用Dispatcher处理,内部主要是一个线程池,不保留存活60秒无限数量

public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }

AsyncCall的run调用execute 是异步发生的callback

@Override protected void execute() {
      boolean signalledCallback = false;
      try {
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          responseCallback.onResponse(RealCall.this, response);
        }
      } catch (IOException e) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          eventListener.callFailed(RealCall.this, e);
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }

response使用了责任链设计模式

1.内部添加了多个拦截器的ArrayList
2.使用index作为索引,调用第一个chain的proceed
3.RealInterceptorChain作为实现,proceed的时候先检查index是否越界(执行结束)
4.新建下一个RealInterceptorChain并传入index+1的位置
5.使用当前的Interceptor 处理下一个RealInterceptorChain;其实就是执行当前的Interceptor的intercept方法,主要内容:用当前Interceptor修改下一个RealInterceptorChain,然后调用下一个RealInterceptorChain的proceed方法,循环处理。(ConnectInterceptor 添加了HttpCodec 传给了下游的CallServerInterceptor)
6.CallServerInterceptor是最后一个拦截器负责请求数据,只会被倒数第二个调用,不再调用下一个了
7.HttpCodec有http1和2的各自实现,CallServerInterceptor联网的过程是用HttpCodec的高层次接口实现的
8.interface HttpCodec接口的实现,最终交给Okio来处理(Sink)
9.对网络的处理,最终是socket的java.io.OutputStream java实现

上一篇下一篇

猜你喜欢

热点阅读