OkHttp源码分析

一、OkHttp整体流程:



二、异步请求

一次异步请求过程:

//1、创建OkHttpClient
OkHttpClient client = new OkHttpClient.Builder().build();

//2、创建Request
Request request = new Request.Builder()
        .url("http://xxx.com") 
        .build();

//3、创建CallCall call = client.newCall(request);

//4、执行Call的异步方法
 call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //做一些请求失败的处理
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
              //做一些请求成功的处理
            }
        });
1、创建OkHttpClient(OkHttpClient )

OkHttpClient表示了HTTP请求的客户端类, 一般 执行一次new OkHttpClient(),将其作为全局的实例进行保存。
设置OkHttpClient的一些参数,比如超时时间、缓存、拦截等。(通过Build模式创建一个OkHttpClient)
2、创建Request( Request

public final class Request {
  private final HttpUrl url;
  private final String method;
  private final Headers headers;
  private final RequestBody body;
  private final Object tag;

  private volatile CacheControl cacheControl; // Lazily initialized.
}

Request类封装了请求报文信息:请求的Url地址、请求的方法(如GET、POST等)、各种请求头(如Content-Type、Cookie)以及可选的请求体。一般通过内部类Request.Builder的链式调用生成Request对象。
3、创建Call:(Call)
(1)Call接口
public interface Call { 
    //返回当前Call的Request 
    Request request(); 
    //同步请求 
    Response execute() throws IOException; 
    //异步请求 
    void enqueue(Callback responseCallback); 
    //取消请求 
    void cancel(); 
    //判断是否执行过
    boolean isExecuted(); 
    //判断是否取消了 
    boolean isCanceled(); 
    //内部含有一个内部接口Factory 用于生成
    Call interface Factory { 
        Call newCall(Request request); 
    } 
}

Call是一个接口,主要定义了进行请求和取消请求等的方法 。内部有一个newCall方法,传入一个Request返回一个Call,为下一步进行网络请求做准备。
(2)RealCall
发起请求的真正的类,实现了Call接口
final class RealCall implements Call {
  private final OkHttpClient client;

  // Guarded by this.
  private boolean executed;
  volatile boolean canceled;

  /** The application's original request unadulterated by redirects or auth headers. */
  Request originalRequest;
  HttpEngine engine;

  protected RealCall(OkHttpClient client, Request originalRequest) {
    this.client = client;
    this.originalRequest = originalRequest;
  }
  .....
}
RealCall的创建是通过OkHttpClient的newCall方法
#OkHttpClient
@Override public Call newCall(Request request) {
   return new RealCall(this, request);
}
4、执行异步请求:
RealCall的enqueue方法
#RealCall
void enqueue(Callback responseCallback) {
    synchronized (this) {
    //同一个Call只能执行一次,否则会报错。
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
  • client.dispatcher():返回的时Dispatcher,Dispatcher是用来管理请求的调度。
  • 调用Dispatcher的enqueue方法。
  • 传入AsyncCall对象
5、Dispatcher
(1)成员变量
public final class Dispatcher {
    //最大并发请求数为64
    private int maxRequests = 64;
    //每个主机最大请求数为5
    private int maxRequestsPerHost = 5;
    //线程池
    private ExecutorService executorService;
    //缓存队列(当runningAsyncCalls的尺寸达到maxRequests参数时(默认64)存储新加的异步请求)
    private final Deque<RealCall.AsyncCall> readyAsyncCalls = new ArrayDeque<>();
    //正在运行的异步请求队列
    private final Deque<RealCall.AsyncCall> runningAsyncCalls = new ArrayDeque<>();
    //正在运行的同步请求队列
    private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
}
(2)enqueue方法
#Dispatcher
synchronized void enqueue(AsyncCall call) {
  //判断请求时否小于最大值,同一主机的request小于最大值
  if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
    runningAsyncCalls.add(call); //加入异步队列
    executorService().execute(call); //线程池执行请求
  } else {
    readyAsyncCalls.add(call);  //加入等待队列
  }
}
6、 AsyncCall
AsyncCall是RealCall的内部类,继承了NamedRunnable,实际上也是一个Runnable实现类。需要实现的是execute方法
#RealCall.AsyncCall:
@Override
protected void execute() {
    boolean signalledCallback = false;
    try {
        //返回Request对象
        Response response = getResponseWithInterceptorChain(forWebSocket);
        if (canceled) {
            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 {
            responseCallback.onFailure(RealCall.this, e);
        }
    } finally {
        //请求完成的操作,调用了Dispatch的finished方法
        client.dispatcher().finished(this);
    }
}
最终获取到了Response对象
7、Response:
Response类封装了响应报文信息:状态吗(200、404等)、响应头(Content-Type、Server等)以及可选的响应体。
(1)通过getResponseWithInterceptorChain获取到Response对象
#RealCall
添加拦截器的操作
private Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    //添加开发者自定义的拦截器
    interceptors.addAll(client.interceptors());
    //添加失败重连和重定向的拦截器
    interceptors.add(retryAndFollowUpInterceptor);
    //主要是添加一些请求头和其它信息,同时对返回的响应做一些响应头或其它处理。
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    //添加缓存拦截器,根据不同的缓存策略做相应的处理。
    interceptors.add(new CacheInterceptor(client.internalCache()));
    //添加连接拦截器,与服务器建立Socket连接。
    interceptors.add(new ConnectInterceptor(client));

    //retryAndFollowUpInterceptor.isForWebSocket() 默认为false
    //默认添加网络拦截器
    if (!retryAndFollowUpInterceptor.isForWebSocket()) {
        interceptors.addAll(client.networkInterceptors());
    }
    //添加 负责向服务器发送请求数据、从服务器读取响应数据的 CallServerInterceptor
    interceptors.add(new CallServerInterceptor(
            retryAndFollowUpInterceptor.isForWebSocket()));
    // 创建一个RealInterceptorChain,用它来开始处理请求。
    Interceptor.Chain chain = new RealInterceptorChain(
            interceptors, null, null, null, 0, originalRequest);
    return chain.proceed(originalRequest);
}
最终创建并调用了RealInterceptorChain 的proceed方法。

8、RealInterceptorChain :实现Interceptor接口
# RealInterceptorChain 
public Response proceed(Request request, StreamAllocation streamAllocation, HttpStream httpStream,
      Connection connection) throws IOException {
  ...
    //创建一个新的RealInterceptorChain用于把Request传递给下一个Interceptor去处理
    RealInterceptorChain next = new RealInterceptorChain(
        interceptors, streamAllocation, httpStream, connection, index + 1, request);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);
  ...
    return response;
  }
能够把Request依次传递给下一个Interceptor去处理。
每一个Interceptor在发送Request的时候只处理自己那一部分Request,然后通过RealInterceptorChain的带动传递给下一个Interceptor进行处理,最后一个Interceptor发送完请求得到服务器的响应Response。
9、Dispatch的finish方法
请求完成后的操作,finish中调用了promoteCalls方法,
#Dispatch
private void promoteCalls() {
    if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
    if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
    //遍历下一个RealCall
    for (Iterator<RealCall.AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
        RealCall.AsyncCall call = i.next();

        if (runningCallsForHost(call) < maxRequestsPerHost) {
            //移除
            i.remove();
            //下一个请求开始
            runningAsyncCalls.add(call);
            executorService().execute(call);
        }

        if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
    }
}
移除本次请求,开始线程池中的下一个请求。

三、同步请求:
区别在于调用了RealCall的execute方法。
#RealCall
@Override
public Response execute() throws IOException {
    synchronized (this) {
    //同一个Call只能执行一次,否则会报错。
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    try {
      //Dispatcher.execute(Call call)方法,只是把当前正在执行的Call添加到代表执行中的集合去。
      client.dispatcher().executed(this);
      //返回响应Response。
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      //对一个Call结束之后做的处理。
      client.dispatcher().finished(this);
    }
}

总结:主要流程
(1)创建一个OkHttpClient对象,设置拦截、缓存、超时时间等信息。
(2)创建一个Request,包括url、请求方法、请求头、请求体等信息。
(3)创建一个RealCall对象,通过OkHttpClient的newCall方法。内部定义了同步、异步请求、取消请求等方法。
(4)异步请求:通过调用RealCall的enqueue方法,内部通过调用Dispatcher的enqueue方法,具体是调用AsyncCall中的execute方法。
         同步请求:通过调用RealCall的execute方法进行处理。
(5)通过Interceptor拦截器进行链式的拦截处理,具体实现是RealInterceptorChain
(6)通过调用RealInterceptorChain的proceed返回响应Response。
(7)在Dispatcher中移除本次请求,开始下次请求。

参考文章:




































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值