# OkHttp原理

## 目录
- [OkHttp架构](#okhttp架构)
- [拦截器机制](#拦截器机制)
- [连接池](#连接池)
- [缓存机制](#缓存机制)
- [请求流程](#请求流程)
- [响应处理](#响应处理)
- [OkHttp源码分析](#okhttp源码分析)
- [面试常见问题](#面试常见问题)

---

## OkHttp架构

### 架构图

```
┌─────────────┐
│   Client    │  ←─── 客户端
└──────┬──────┘
       │
┌──────▼──────┐
│  Interceptor│  ←─── 拦截器链
└──────┬──────┘
       │
┌──────▼──────┐
│ Connection  │  ←─── 连接管理
└──────┬──────┘
       │
┌──────▼──────┐
│   Network   │  ←─── 网络层
└─────────────┘
```

### 核心组件

```java
// OkHttpClient：客户端配置
OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .build();

// Request：请求
Request request = new Request.Builder()
    .url("https://www.example.com")
    .build();

// Call：执行请求
Call call = client.newCall(request);
Response response = call.execute();
```

---

## 拦截器机制

### 拦截器链

```java
// 拦截器链：责任链模式
// 请求：Client → Interceptor1 → Interceptor2 → ... → Network
// 响应：Network → ... → Interceptor2 → Interceptor1 → Client

public class MyInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        
        // 请求前处理
        Request newRequest = request.newBuilder()
            .addHeader("Authorization", "Bearer token")
            .build();
        
        // 执行请求
        Response response = chain.proceed(newRequest);
        
        // 响应后处理
        return response;
    }
}
```

### 内置拦截器

```java
// 1. RetryAndFollowUpInterceptor：重试和重定向
// 2. BridgeInterceptor：添加请求头
// 3. CacheInterceptor：缓存处理
// 4. ConnectInterceptor：建立连接
// 5. CallServerInterceptor：发送请求
```

### 自定义拦截器

```java
// 日志拦截器
public class LoggingInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        long startTime = System.currentTimeMillis();
        
        Response response = chain.proceed(request);
        
        long endTime = System.currentTimeMillis();
        Log.d("OkHttp", String.format(
            "Request: %s, Duration: %dms",
            request.url(), endTime - startTime
        ));
        
        return response;
    }
}

// 使用
OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new LoggingInterceptor())
    .build();
```

---

## 连接池

### 连接池原理

```java
// ConnectionPool：连接池
// 复用 TCP 连接，减少建立连接的开销

// 连接池配置
ConnectionPool pool = new ConnectionPool(10, 5, TimeUnit.MINUTES);
// 最大连接数：10
// 空闲连接存活时间：5分钟

OkHttpClient client = new OkHttpClient.Builder()
    .connectionPool(pool)
    .build();
```

### 连接复用

```java
// HTTP/1.1：Keep-Alive
// 同一个连接可以处理多个请求

// HTTP/2：多路复用
// 一个连接可以同时处理多个请求
```

---

## 缓存机制

### 缓存配置

```java
// 配置缓存
int cacheSize = 10 * 1024 * 1024; // 10MB
Cache cache = new Cache(context.getCacheDir(), cacheSize);

OkHttpClient client = new OkHttpClient.Builder()
    .cache(cache)
    .build();
```

### 缓存策略

```java
// 使用 Cache-Control 头控制缓存
Request request = new Request.Builder()
    .url("https://www.example.com")
    .cacheControl(CacheControl.FORCE_CACHE) // 强制使用缓存
    .build();

// 或
Request request = new Request.Builder()
    .url("https://www.example.com")
    .cacheControl(new CacheControl.Builder()
        .maxAge(3600, TimeUnit.SECONDS)
        .build())
    .build();
```

---

## 请求流程

### 请求执行流程

```
1. 创建 Request
2. 创建 Call
3. 执行拦截器链
   - RetryAndFollowUpInterceptor
   - BridgeInterceptor
   - CacheInterceptor
   - ConnectInterceptor
   - CallServerInterceptor
4. 返回 Response
```

### 异步请求

```java
// 异步请求
Call call = client.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // 请求失败
    }
    
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        // 请求成功
        String body = response.body().string();
    }
});
```

---

## 响应处理

### 响应解析

```java
// 同步请求
Response response = call.execute();
if (response.isSuccessful()) {
    String body = response.body().string();
    // 处理响应体
}

// 异步请求
call.enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            String body = response.body().string();
            // 处理响应体
        }
    }
});
```

### 响应流

```java
// 读取响应流
ResponseBody body = response.body();
InputStream is = body.byteStream();
// 使用流读取
```

---

## OkHttp源码分析

### 核心类

```java
// OkHttpClient：客户端配置
// Request：请求对象
// Response：响应对象
// Call：执行请求的接口
// RealCall：Call 的实现
// Interceptor：拦截器接口
// ConnectionPool：连接池
// Cache：缓存
```

### 关键流程

```java
// 1. 创建 Call
Call call = client.newCall(request);

// 2. 执行请求
Response response = call.execute();

// 3. 拦截器链处理
// 4. 建立连接
// 5. 发送请求
// 6. 接收响应
```

---

## 面试常见问题

### Q1: OkHttp 的拦截器机制？

**答案：**
- 使用责任链模式
- 请求和响应都经过拦截器链
- 可以添加自定义拦截器

### Q2: OkHttp 的连接池？

**答案：**
- 复用 TCP 连接
- 减少建立连接的开销
- 支持 HTTP/1.1 Keep-Alive 和 HTTP/2 多路复用

### Q3: OkHttp 的缓存机制？

**答案：**
- 使用 Cache-Control 头控制缓存
- 支持内存和磁盘缓存
- 自动处理缓存验证

### Q4: OkHttp 的请求流程？

**答案：**
1. 创建 Request
2. 创建 Call
3. 执行拦截器链
4. 建立连接
5. 发送请求
6. 接收响应

---

*最后更新：2024年*
