美文网首页
Retrofit 分析

Retrofit 分析

作者: 水清波 | 来源:发表于2019-05-29 17:13 被阅读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实现

    相关文章

      网友评论

          本文标题:Retrofit 分析

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