OkHttp和Retrofit

介绍

OkHttp

OkHttp是由Square公司提供的处理网络请求的开源库,有以下特性:

  1. 支持Http2.0,对一台机器的所有请求共享同一个socket
  2. 内置连接池,支持连接复用,减少延迟
  3. Interceptors(拦截器)轻松处理请求与响应,支持透明的GZIP压缩响应体
  4. 请求失败时自动重连
  5. 拥有队列线程池,轻松写并发
  6. 基于Headers的缓存策略

Retrofit

Retrofit也是Square公司产品,是对OkHttp的封装,将网络请求交给OkHttp,自身就可以通过简单的配置就可以进行网络请求了(后面讨论的Retrofit都是2.0版本)

  1. 请求可以通过注解的方式定制
  2. 支持同步、异步和RXjava
  3. 解耦
  4. 可以对json、xml等响应数据通过不同的反序列工具来解耦
  5. 设置网络请求日志(很多好用的api)

使用方法

不做具体介绍,可以看官方使用文档:OkHttp、Retrofit

  1. 同步请求
  2. 异步请求
  3. get请求
  4. post请求
  5. 缓存设置
  6. 取消缓存
  7. 支持请求回调,直接返回对象、对象集合

请求流程

OkHttp和Retrofit_第1张图片

OkHttp请求流程

OkHttp部分源码解析

* newCall--实际是调用realCall

            protected RealCall(OkHttpClient client, Request originalRequest) {  
                this.client = client;    
                this.originalRequest = originalRequest;    
                this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client); 
            }
    * excuate()--先判断这个请求是否执行了,然后通过getResponseWithInterceptorChain()获取响应

            @Override
         public Response execute() throws IOException {
            synchronized (this) {
                if (executed) throw new IllegalStateException("Already Executed"); //(1)
                executed = true;
            }
            try {
                client.dispatcher.executed(this);//(2)
                Response result = getResponseWithInterceptorChain();//(3)
                if (result == null) throw new IOException("Canceled");
                return result;
            }finally {
                client.dispatcher.finished(this);//(4)
            }
        }

    * getResponseWithInterceptorChain()--使用拦截器的责任链获取响应,然后proceed()开始执行链式拦截器

        //将拦截器链式加入,通过链式调用
        //拦截器的作用:拦截器是OkHttp框架提供的对http的请求和响应进行同意处理的机制
        //多个拦截器还可以连接形成一个链再使用,拦截器会按照链式上的顺序依次执行
        //拦截器会先对请求进行修改,然后获取响应之后也会对响应进行修改
     private Response getResponseWithInterceptorChain() throws IOException {
         // Build a full stack of interceptors.
         List interceptors = new ArrayList<>();
         interceptors.addAll(client.interceptors());     //(1)
         interceptors.add(retryAndFollowUpInterceptor);    //(2)
         interceptors.add(new BridgeInterceptor(client.cookieJar()));    //(3)
         interceptors.add(new CacheInterceptor(client.internalCache()));    //(4)
         interceptors.add(new ConnectInterceptor(client));    //(5)
         if (!retryAndFollowUpInterceptor.isForWebSocket()) {
             interceptors.addAll(client.networkInterceptors());    //(6)
         }
         interceptors.add(new CallServerInterceptor(
                 retryAndFollowUpInterceptor.isForWebSocket()));     //(7)

         Interceptor.Chain chain = new RealInterceptorChain(
                 interceptors, null, null, null, 0, originalRequest);
         return chain.proceed(originalRequest); //  <<=========开始链式调用
     }

    * proceed()--实例化一个RealIterceptorChain对象,在一个存放Interceptor的ArrayList中获取当前的Interceptor,
        当前的Interceptor.intercept()方法调用RealIterceptorChain,并传递

       public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
         Connection connection) throws IOException {
        if (index >= interceptors.size()) throw new AssertionError();

        calls++;

        // If we already have a stream, confirm that the incoming request will use it.
        //如果我们已经有一个stream。确定即将到来的request会使用它
        if (this.httpCodec != null && !sameConnection(request.url())) {
          throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
              + " must retain the same host and port");
        }

        // If we already have a stream, confirm that this is the only call to chain.proceed().
        //如果我们已经有一个stream, 确定chain.proceed()唯一的call
        if (this.httpCodec != null && calls > 1) {
          throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
              + " must call proceed() exactly once");
        }

        // Call the next interceptor in the chain.
        //调用链的下一个拦截器
        RealInterceptorChain next = new RealInterceptorChain(
            interceptors, streamAllocation, httpCodec, connection, index + 1, request);
        Interceptor interceptor = interceptors.get(index);
        Response response = interceptor.intercept(next);

        // Confirm that the next interceptor made its required call to chain.proceed().
        if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
          throw new IllegalStateException("network interceptor " + interceptor
              + " must call proceed() exactly once");
        }

        // Confirm that the intercepted response isn't null.
        if (response == null) {
          throw new NullPointerException("interceptor " + interceptor + " returned null");
        }

        return response;
      }

Retrofit请求流程

OkHttp和Retrofit_第2张图片

1、创建Retrofit

Retrofit retrofit = new Retrofit.Builder().baseUrl("").build();

Builder()源码:
其作用:
1. Platform.get()通过反射的方式判断其平台是Android是Java
2. 设置转换器工厂列表 converterFactories
3. 设置Call适配器工厂列表 callAdapterFactories

 Builder(Platform platform) {
            this.converterFactories = new ArrayList();
            this.callAdapterFactories = new ArrayList();
            this.platform = platform;
        }
 public Builder() {
           this(Platform.get());
        }

2. 代理模式,创建动态代理类

RxHttpService apiStores = retrofit.create(RxHttpService.class);

crete()源码:
其作用:
1. eagerlyValidateMethods()验证所有service类中所有的方法
2. 获取一个代理实例,通过反射的方法暴露invoke()可以调用所有的方法
ServiceMethod:Method的所有列表,之前会有个缓存列表serviceMethodCache判断Method是否存在

public  T create(final Class service) {
      Utils.validateServiceInterface(service);
      if(this.validateEagerly) {
          this.eagerlyValidateMethods(service);
      }

      return Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
          private final Platform platform = Platform.get();

          public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
              if(method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
              } else if(this.platform.isDefaultMethod(method)) {
                  return this.platform.invokeDefaultMethod(method, service, proxy, args);
              } else {
                  ServiceMethod serviceMethod = Retrofit.this.loadServiceMethod(method);
                  OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
                  return serviceMethod.adapt(okHttpCall);
              }
          }
      });
  } 
  

3.CallAdapter
Request装换成OkHttpCall

4. execute()和enqueue()
同步和异步的方式将OkHttpCall抛给OkHttp执行,具体流程见上面(OkHttp请求步骤)

涉及到的设计模式

  1. Builder模式(创建Retrofit)
  2. 工厂模式(创建CallAdapter & Converter)
  3. 适配器模式 (CallAdapter)
  4. 代理模式(静态:ExecutorCallbackCall;动态:Retrofit.create(xxx.class))

你可能感兴趣的:(源码解析,总结)