OkHttp是什么
先引用一段来自官方的介绍
HTTP是现代应用程序网络的方式。这就是我们交换数据和媒体的方式。有效地执行HTTP可以使您的内容加载更快,并节省带宽。
OkHttp是默认情况下有效的HTTP客户端:
- HTTP / 2支持允许对同一主机的所有请求共享一个套接字。
- 连接池可减少请求延迟(如果HTTP / 2不可用)。
- 透明的GZIP缩小了下载大小。
- 响应缓存可以完全避免网络重复请求。
当网络出现问题时,OkHttp会坚持不懈:它将从常见的连接问题中静默恢复。如果您的服务具有多个IP地址,则在第一次连接失败时,OkHttp将尝试使用备用地址。这对于IPv4 + IPv6和冗余数据中心中托管的服务是必需的。OkHttp支持现代TLS功能(TLS 1.3,ALPN,证书固定)。可以将其配置为回退以获得广泛的连接性。
使用OkHttp很容易。它的请求/响应API具有流畅的构建器和不变性。它支持同步阻塞调用和带有回调的异步调用。
从上述官方介绍中可以了解到OkHttp是一个网络库,具有有共享socket链接、连接池缓存、GZIP压缩、响应缓存、自动重连等特点,从而可以使得网络请求更加高效,并且更加节省带宽。在此同时OkHttp支持重连,并且API丰富,使用简单。
关于OkHttp特性简要概括
- 共享链接和连接池缓存:通过在StreamAllocation#findConnection(),在findConnection方法中首先调动 ConnectionPool#get() 尝试获取有效链接,如果获取失败则创建RealConnection 实例,并通过ConnectionPool#put() 放入连接池队列。
- GZIP 压缩:通过BridgeInterceptor拦截器实现,在拦截器判断如果没有设置“Accept-Encoding”,拦截器会默认添加Accept-Encoding=gzip,同时会对response进行解压缩处理。
- 缓存:通过CacheInterceptor拦截器实现,通过CacheStrategy来控制是否使用缓存。
- 自动重连:通过RetryAndFollowUpInterceptor拦截器实现,失败后自动重连,从代码中可以看到 MAX_FOLLOW_UPS 重连次数为20。
OkHttp接入要求
OkHttp 最新的API要求在Android 5.0+(API级别21+)和Java 8+上运行。
OkHttp 3.12.x分支支持Android 2.3+(API级别9+)和Java 7+。这些平台不支持TLS 1.2,因此不建议使用。
OkHttp使用方式
引用Maven依赖
implementation("com.squareup.okhttp3:okhttp:4.7.2")
Get 同步请求
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
Get 异步请求
OkHttpClient client = new OkHttpClient();
void run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
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 {
}
});
}
Post请求
public static final MediaType JSON
= MediaType.get("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
Post 异步请求
public static final MediaType JSON
= MediaType.get("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
void post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
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 {
}
});
}