OkHttp 是 Square 公司开发的高效、轻量、稳定的 HTTP/HTTPs 客户端,是 Android 开发、Java 后端最主流的网络请求库,替代了原生的 HttpURLConnection。

它的核心优势:

  • 支持 HTTP/2、连接池、GZIP 自动压缩、缓存
  • 同步 / 异步请求、拦截器(日志、请求头统一处理)
  • 超时、重连、错误处理完善
  • 安卓项目几乎必用,也是 Retrofit 的底层依赖

一、快速集成(Gradle)

1. Android / Java 项目依赖

最新稳定版(以官方为准):

gradle

// OkHttp 核心
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
// 可选:日志拦截器(查看请求/响应日志)
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'

2. 权限(Android 必备)

AndroidManifest.xml 添加:

xml

<uses-permission android:name="android.permission.INTERNET" />

二、基础使用(最常用 4 种请求)

1. 创建全局 OkHttp 实例(推荐单例)

OkHttp 官方强烈建议全局单例,避免重复创建连接池导致性能问题:

java

运行

import okhttp3.OkHttpClient;
import java.util.concurrent.TimeUnit;

public class HttpUtil {
    // 全局单例 OkHttpClient
    public static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)   // 连接超时
            .readTimeout(10, TimeUnit.SECONDS)      // 读取超时
            .writeTimeout(10, TimeUnit.SECONDS)     // 写入超时
            // .addInterceptor(new LogInterceptor())  // 自定义拦截器
            .build();
}

2. GET 请求(异步 → 安卓推荐)

java

运行

// 1. 构建 Request
Request request = new Request.Builder()
        .url("https://api.github.com/users/octocat")
        .get()  // GET 请求(默认可不写)
        .addHeader("token", "xxx")  // 请求头
        .build();

// 2. 异步请求(不阻塞主线程)
HttpUtil.OK_HTTP_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 {
        // 请求成功
        if (response.isSuccessful()) {
            String result = response.body().string();
            // 处理结果
        }
        response.close(); // 必须关闭
    }
});

3. POST 请求(表单提交)

java

运行

// 构建表单参数
RequestBody formBody = new FormBody.Builder()
        .add("username", "test")
        .add("password", "123456")
        .build();

// 构建请求
Request request = new Request.Builder()
        .url("https://xxx.com/login")
        .post(formBody)
        .build();

// 执行请求(同上异步)

4. POST 请求(JSON 提交)

java

运行

// JSON 字符串
String json = "{\"name\":\"okhttp\",\"age\":18}";

// 构建请求体
RequestBody requestBody = RequestBody.create(
        json,
        MediaType.parse("application/json; charset=utf-8")
);

Request request = new Request.Builder()
        .url("https://xxx.com/api")
        .post(requestBody)
        .build();

三、高级功能

1. 日志拦截器(调试神器)

添加依赖后直接使用,可打印完整请求 / 响应

java

运行

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY); // 打印全部信息

OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(logging)
        .build();

2. 拦截器统一处理(请求头、Token)

java

运行

public class HeaderInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();
        
        // 所有请求统一添加请求头
        Request newRequest = original.newBuilder()
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + getToken())
                .method(original.method(), original.body())
                .build();
        
        return chain.proceed(newRequest);
    }
}

3. 文件上传

java

运行

// 文件
File file = new File("path/test.jpg");

// 构建多部分请求体
RequestBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("file", file.getName(),
                RequestBody.create(file, MediaType.parse("image/jpeg")))
        .build();

Request request = new Request.Builder()
        .url("https://xxx.com/upload")
        .post(requestBody)
        .build();

四、注意事项(必看)

  1. response.body().string() 只能调用一次 内部是流,读取后会关闭,多次调用会抛异常。
  2. Android 不能在主线程做同步请求 同步 execute() 会触发 NetworkOnMainThreadException,必须用异步 enqueue()
  3. 必须关闭 Response 否则会造成资源泄漏,建议 try-finally 关闭。
  4. 单例使用 不要每次请求都 new OkHttpClient()

总结

  1. OkHttp 是 Java/Android 最稳定高效的 HTTP 客户端
  2. 支持 GET/POST/JSON/ 文件上传 / 拦截器 / 缓存
  3. 安卓开发必须用异步请求,避免主线程阻塞
  4. 最佳实践:全局单例 + 拦截器统一处理

更多推荐