OkHttp 源码分析-深入篇

1. 简介

OkHttp 是一个高效的 HTTP 客户端,广泛应用于 Android 和 Java 应用中。它支持同步和异步请求、连接池、透明压缩和缓存等特性。本文将深入分析 OkHttp 的源码,揭示其实现原理。

2. 项目结构

OkHttp 的项目结构大致如下:


okhttp/
│
├── okhttp/src/main/java/okhttp3/
│   ├── Cache.java
│   ├── Call.java
│   ├── Callback.java
│   ├── ConnectionPool.java
│   ├── Dispatcher.java
│   ├── Interceptor.java
│   ├── OkHttpClient.java
│   ├── Request.java
│   ├── Response.java
│   └── internal/
│       ├── cache/
│       ├── connection/
│       ├── http/
│       └── ws/

各个文件的功能如下:

  • Cache.java:实现 HTTP 缓存。
  • Call.java:表示一次 HTTP 请求。
  • Callback.java:异步请求回调接口。
  • ConnectionPool.java:管理 HTTP 连接池。
  • Dispatcher.java:管理并发请求的调度。
  • Interceptor.java:拦截器机制。
  • OkHttpClient.java:OkHttp 的核心类,配置和执行 HTTP 请求。
  • Request.java:表示一个 HTTP 请求。
  • Response.java:表示一个 HTTP 响应。
  • internal/:内部实现类,包括缓存、连接和 HTTP 协议处理等。

3. 核心类分析

3.1 OkHttpClient 类

OkHttpClient 是 OkHttp 的核心类,用于配置和执行 HTTP 请求。


public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
    final Dispatcher dispatcher;
    final ConnectionPool connectionPool;
    final List<Interceptor> interceptors;
    final List<Interceptor> networkInterceptors;
    final Cache cache;
    // 其他字段省略

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

    private OkHttpClient(Builder builder) {
        this.dispatcher = builder.dispatcher;
        this.connectionPool = builder.connectionPool;
        this.interceptors = Util.immutableList(builder.interceptors);
        this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
        this.cache = builder.cache;
        // 其他初始化代码省略
    }

    public Call newCall(Request request) {
        return RealCall.newRealCall(this, request, false);
    }

    public static final class Builder {
        Dispatcher dispatcher;
        ConnectionPool connectionPool;
        List<Interceptor> interceptors = new ArrayList<>();
        List<Interceptor> networkInterceptors = new ArrayList<>();
        Cache cache;
        // 其他字段省略

        public Builder() {
            this.dispatcher = new Dispatcher();
            this.connectionPool = new ConnectionPool();
        }

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

OkHttpClient 类通过 Builder 模式进行配置和构建。newCall 方法创建一个新的 HTTP 请求。

3.2 Call 接口与 RealCall 类

Call 接口表示一次 HTTP 请求,RealCall 是其具体实现。


public interface Call extends Cloneable {
    Request request();
    Response execute() throws IOException;
    void enqueue(Callback responseCallback);
    void cancel();
    boolean isExecuted();
    boolean isCanceled();
    Call clone();
}

final class RealCall implements Call {
    private final OkHttpClient client;
    private final Request originalRequest;
    private boolean executed;

    private RealCall(OkHttpClient client, Request originalRequest) {
        this.client = client;
        this.originalRequest = originalRequest;
    }

    static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
        RealCall call = new RealCall(client, originalRequest);
        return call;
    }

    @Override
    public Request request() {
        return originalRequest;
    }

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

    @Override
    public void enqueue(Callback responseCallback) {
        synchronized (this) {
            if (executed) throw new IllegalStateException("Already Executed");
            executed = true;
        }
        client.dispatcher().enqueue(new AsyncCall(responseCallback));
    }

    // 其他方法省略

    Response getResponseWithInterceptorChain() throws IOException {
        List<Interceptor> interceptors = new ArrayList<>();
        interceptors.addAll(client.interceptors());
        interceptors.add(new RetryAndFollowUpInterceptor(client));
        interceptors.add(new BridgeInterceptor(client.cookieJar()));
        interceptors.add(new CacheInterceptor(client.internalCache()));
        interceptors.add(new ConnectInterceptor(client));
        if (!forWebSocket) {
            interceptors.addAll(client.networkInterceptors());
        }
        interceptors.add(new CallServerInterceptor(forWebSocket));

        Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest, this, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis());
        return chain.proceed(originalRequest);
    }
}

RealCall 实现了 Call 接口,通过 execute 方法同步执行请求,通过 enqueue 方法异步执行请求。getResponseWithInterceptorChain 方法构建了拦截器链并执行请求。

3.3 Dispatcher 类

Dispatcher 类负责管理并发请求的调度。


public final class Dispatcher {
    private int maxRequests = 64;
    private int maxRequestsPerHost = 5;
    private final Deque<RealCall.AsyncCall> readyAsyncCalls = new ArrayDeque<>();
    private final Deque<RealCall.AsyncCall> runningAsyncCalls = new ArrayDeque<>();
    private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

    public synchronized void enqueue(RealCall.AsyncCall call) {
        if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
            runningAsyncCalls.add(call);
            executorService().execute(call);
        } else {
            readyAsyncCalls.add(call);
        }
    }

    public synchronized void executed(RealCall call) {
        runningSyncCalls.add(call);
    }

    public synchronized void finished(RealCall.AsyncCall call) {
        if (!runningAsyncCalls.remove(call)) throw new AssertionError("AsyncCall wasn't running!");
        promoteCalls();
    }

    public synchronized void finished(RealCall call) {
        if (!runningSyncCalls.remove(call)) throw new AssertionError("Call wasn't running!");
        promoteCalls();
    }

    private void promoteCalls() {
        if (runningAsyncCalls.size() >= maxRequests) return;
        if (readyAsyncCalls.isEmpty()) return;

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

    private int runningCallsForHost(RealCall.AsyncCall call) {
        int result = 0;
        for (RealCall.AsyncCall c : runningAsyncCalls) {
            if (c.host().equals(call.host())) result++;
        }
        return result;
    }

    // 其他方法省略
}

Dispatcher 负责管理请求的并发执行,通过 enqueue 方法将异步请求加入队列,通过 promoteCalls 方法调度请求执行。

3.4 Interceptor 接口与 RealInterceptorChain 类

Interceptor 接口用于实现拦截器机制,RealInterceptorChain 类负责拦截器链的执行。


public interface Interceptor {
    Response intercept(Chain chain) throws IOException;

    interface Chain {
        Request request();
        Response proceed(Request request) throws IOException;
        Connection connection();
    }
}

public final class RealInterceptorChain implements Interceptor.Chain {
    private final List<Interceptor> interceptors;
    private final int index;
    private final Request request;
    private final Call call;
    private final int connectTimeout;
    private final int readTimeout;
    private final int writeTimeout;

    RealInterceptorChain(List<Interceptor> interceptors, Call call, Request request, int index, int connectTimeout, int readTimeout, int writeTimeout) {
        this.interceptors = interceptors;
        this.call = call;
        this.request = request;
        this.index = index;
        this.connectTimeout = connectTimeout;
        this.readTimeout = readTimeout;
        this.writeTimeout = writeTimeout;
    }

    @Override
    public Request request() {
        return request;
    }

    @Override
    public Response proceed(Request request) throws IOException {
        if (index >= interceptors.size()) throw new AssertionError();

        RealInterceptorChain next = new RealInterceptorChain(interceptors, call, request, index +

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值