OkHttp3源码--请求流程

一、OkHttp3的使用

流程:

同步:

Response response = client.newCall(request).execute();

异步:

client.newCall(request).enqueue(new Callback() {});
1、创建OkHttpClient客户端

a、

OkHttpClient client = new OkHttpClient();

b、

OkHttpClient okHttpClient = new OkHttpClient.Builder()
    .addInterceptor(interceptor)
    .connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS)
    .addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request()
                .newBuilder()
                .build();
            return chain.proceed(request);
        }
    })
    .build();
2、创建Request请求体
Request request = new Request.Builder()
    .url(url)
    .build();
3、执行请求

a、同步请求

Response response = client.newCall(request).execute();

b、异步请求

client.newCall(request).enqueue(new Callback() {
    @Override 
    public void onFailure(Call call, IOException e) {
        e.printStackTrace();
    }

    @Override 
    public void onResponse(Call call, Response response) throws IOException {
        ...
    });

二、OkHttp3请求流程

1、创建OkHttpClient客户端;
client...
2、调用newCall方法添加请求体Request;
client.newCall(request)...;
3、newCall方法实际调用RealCall类的newRealCall方法;
@Override 
public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
}
4、执行execute()或者enqueue()方法;
5、拦截器处理;
Response result = getResponseWithInterceptorChain();
6、最后返回请求结果;

三、源码分析

1、创建OkHttpClient客户端
OkHttpClient client = new OkHttpClient();

OkHttpClient构造方法,默认通过Builder创建,此时参数均为默认

public OkHttpClient() {
    this(new Builder());
}

Builder模式,初始化OkHttpClient参数

public Builder() {
    dispatcher = new Dispatcher();
    protocols = DEFAULT_PROTOCOLS;
    ...
}

指定具体参数(非默认)时,调用该方法生效

public OkHttpClient build() {
    return new OkHttpClient(this);
}

指定具体参数后调用该方法使其生效

OkHttpClient(Builder builder) {
    this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    ...
}
2、Request的创建
Request request = new Request.Builder().url(url).build();

创建方式同OkHttpClient,Builder模式

public Builder() {
    this.method = "GET";
    this.headers = new Headers.Builder();
}
Builder(Request request) {
    this.url = request.url;
    this.method = request.method;
    ...
}
public Request build() {
    if (url == null) throw new IllegalStateException("url == null");
    return new Request(this);
}
Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    ...
}
3、OkHttpClient的newCall方法
Response response = client.newCall(request).xxx();

这里的newCall方法具体执行的是RealCall类的newRealCall方法

@Override public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
}

真正创建call的地方

static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.eventListener = client.eventListenerFactory().create(call);
    return call;
}
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    ...
}
4、同步请求execute()
Response response = client.newCall(request).execute();

上一步提到这里的Call具体实现是RealCall类(Call只是个接口),所以这里执行的是RealCall类的execute()方法;

@Override 
public Response execute() throws IOException {
    synchronized (this) {
        // 同步请求只执行一次,被标记为已经执行的不会再执行
        if (executed) throw new IllegalStateException("Already Executed");
        executed = true;
    }
    captureCallStackTrace();
    timeout.enter();
    eventListener.callStart(this);
    try {
        // 由dispatcher将请求放入同步请求队列,这里可以看到执行同步请求并不是立即执行,而是将其放入请求队列,由队列出维护
        client.dispatcher().executed(this);
        // 拦截器相关处理,最终返回请求结果
        Response result = getResponseWithInterceptorChain();
        if (result == null) throw new IOException("Canceled");
        return result;
    } catch (IOException e) {
        e = timeoutExit(e);
        eventListener.callFailed(this, e);
        throw e;
    } finally {
        // 最终由dispatcher将请求移出请求同步请求队列
        client.dispatcher().finished(this);
    }
}

添加拦截器,并调用RealInterceptorChain类的proceed方法

Response getResponseWithInterceptorChain() throws IOException {
    ...
    Interceptor.Chain chain = new RealInterceptorChain(interceptors,null,null, null,0,originalRequest,this,eventListener,client.connectTimeoutMillis(),client.readTimeoutMillis(), client.writeTimeoutMillis());    
    return chain.proceed(originalRequest);
}

RealInterceptorChain # proceed

@Override 
public Response proceed(Request request) throws IOException {
return proceed(request, streamAllocation, httpCodec, connection);
}

真正执行的方法

public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, RealConnection connection) throws IOException {
    ...
    // 实例化下一个拦截器的Chain对象
    RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, writeTimeout);
    // 拿到当前的拦截器
    Interceptor interceptor = interceptors.get(index);
    // 调用当前拦截器的intercept方法,并将下一个拦截器的Chain对象传递,直到最后得到response
    Response response = interceptor.intercept(next);
    ...
    if (response.body() == null) {
        throw new IllegalStateException("interceptor " + interceptor + " returned a response with no body");
    }
    return response;
}
5、异步请求enqueue()
 Response response = client.newCall(request).enqueue();

Call的具体实现类RealCall中:

@Override 
public void enqueue(Callback responseCallback) {
    // 同理,执行情况标记
    synchronized (this) {
        if (executed) throw new IllegalStateException("Already Executed");
        executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    // 执行Dispatcher的enqueue()方法,将一个异步请求放入异步请求队列
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
}

Dispatcher# enqueue():

void enqueue(AsyncCall call) {
    synchronized (this) {
    // 放入准备异步请求队列
    readyAsyncCalls.add(call);
}
    promoteAndExecute();
}

Dispatcher# promoteAndExecute():

private boolean promoteAndExecute() {
    assert (!Thread.holdsLock(this));
    List executableCalls = new ArrayList<>();
    boolean isRunning;
    synchronized (this) {
    // 逐个从异步请求队列中取出请求
    for (Iterator i = readyAsyncCalls.iterator(); i.hasNext(); ) {
        AsyncCall asyncCall = i.next();
        // 正在运行的队列是否已经达到最大数
        if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
        // call占用的host小于最大数量
        if (runningCallsForHost(asyncCall) >= maxRequestsPerHost) continue; // Host max capacity.
i.remove();
        // 将请求添加到可执行队列
        executableCalls.add(asyncCall);
        // 将请求添加到正在执行的队列
        runningAsyncCalls.add(asyncCall);
    }
        isRunning = runningCallsCount() > 0;
    }
    for (int i = 0, size = executableCalls.size(); i < size; i++) {
        AsyncCall asyncCall = executableCalls.get(i);
        // 创建一个线程池,由RealCall中的AsyncCall去执行
        asyncCall.executeOn(executorService());
    }
    return isRunning;
}

AsyncCall类

final class AsyncCall extends NamedRunnable {
    ...
    void executeOn(ExecutorService executorService) {
        assert (!Thread.holdsLock(client.dispatcher()));
        boolean success = false;
        try {
            // 由线程池去具体执行异步请求
            executorService.execute(this);
            success = true;
        } catch (RejectedExecutionException e) {
            InterruptedIOException ioException = new InterruptedIOException("executor rejected");
            ioException.initCause(e);
            eventListener.callFailed(RealCall.this, ioException);
            responseCallback.onFailure(RealCall.this, ioException);
        } finally {
            if (!success) {
                client.dispatcher().finished(this); // This call is no longer running!
            }
        }
}

最终执行到这里

@Override 
protected void execute() {
    boolean signalledCallback = false;
    timeout.enter();
    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) {
        e = timeoutExit(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);
    }
}
6、拦截器处理

拦截器处理相关代码

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List interceptors = new ArrayList<>();
    // 将创建OkHttpClient对象时设置的拦截器添加进来
    interceptors.addAll(client.interceptors());
    // 失败重试及重定向,该对象在RealCall构造方法中初始化
    interceptors.add(retryAndFollowUpInterceptor);
    // 请求时添加必要的Header信息,获取响应时移除必要的Header
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    // 缓存相关的拦截器
    interceptors.add(new CacheInterceptor(client.internalCache()));
    // 网络连接,和服务器连接
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
    // 配置 OkHttpClient 时设置的 networkInterceptors
        interceptors.addAll(client.networkInterceptors());
    }
    // 负责向服务器发送请求数据、从服务器读取响应数据
    interceptors.add(new CallServerInterceptor(forWebSocket));
    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest, this, eventListener, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}

你可能感兴趣的:(OkHttp3源码--请求流程)