OkHttp源码分析

48 阅读2分钟

kHttp介绍

OkHttp是当下Android使用最频繁的网络请求框架,由Square公司开源。Google在Android4.4以后开始将源码中 的HttpURLConnection底层实现替换为OKHttp,同时现在流行的Retrofit框架底层同样是使用OKHttp的。

优点:

  • 支持Http1、Http2、Quic以及WebSocket
  • 连接池复用底层TCP(Socket),减少请求延时
  • 无缝的支持GZIP减少数据流量
  • 缓存响应数据减少重复的网络请求
  • 请求失败自动重试主机的其他ip,自动重定向 …….

使用流程

image.png


import java.io.IOException;

public class OkHttpExample {

    private final OkHttpClient client = new OkHttpClient();

    // 异步请求示例
    public void runAsyncRequest(String url) {
        Request request = new Request.Builder()
                .url(url)
                .build();

        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 {
                System.out.println(response.body().string());
            }
        });
    }

    // 同步请求示例
    public void runSyncRequest(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();

        try (Response response = client.newCall(request).execute()) {
            System.out.println(response.body().string());
        }
    }

    public static void main(String[] args) {
        OkHttpExample example = new OkHttpExample();
        String url = "https://jsonplaceholder.typicode.com/posts/1";
        try {
            example.runSyncRequest(url);
            example.runAsyncRequest(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在使用OkHttp发起一次请求时,对于使用者最少存在 OkHttpClientOkHttpClient 和 Request 的创建可以使用它为我们提供的 Builde给OkHttpClient之后返回的一个已准备好执行的请求。

建造者模式:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。实例化

OKHttpClient和Request的时候,因为有太多的属性需要设置,而且开发者的需求组合千变万化,使用建造 者模式可以让用户不需要关心这个类的内部细节,配置好后,建造者会帮助我们按部就班的初始化表示对象

同时OkHttp在设计时采用的门面模式,将整个系统的复杂性给隐藏起来,将子系统接口通过一个客户端 OkHttpClient统一暴露出来。OkHttpClient中全是一些配置,比如代理、ssl证书的配置,而call本身是一个接口,我们获得的实际上是一个ReallCall

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