近日,部分内一个小伙伴在Android开发中选择使用了OKHttp3作为HTTP库;但问其使用原因,他告诉我:”看到别人使用,自己也使用“。我建议他简单了解下使用库的基本原理;对于工程师来说,不必要做的是重复造轮子;但于此同时,一个优秀的工程师还是很有必要了解轮子的原理,从来方便驾驶的时候可以有更好的加上性能。恰好,我个人也有时间,就简单搜集了下OKHttp3的相关资料,并给他进行了简单交流。
一、OKHttp3是什么
OKHttp3本质是一个Http包,具有HTTP协议的主要功能。与传统的HTTP不同的是,OKHttp3具有如下特点:
1)支持HTTP2,允许所有同一个主机地址的请求共享同一个socket连接;
2)连接池减少请求延时;
3)透明的GZIP压缩减少响应数据的大小;
4)缓存响应内容,避免一些完全重复的请求。
这些特性,都是好特性,HTTP2、连接池、压缩、缓存都特性,更是让OKHttp3的访问小略足够高。
二、用法:同步、异步、拦截器
熟悉用HTTP的工程师,一定都记得HTTP的主要操作为GET、POST、PUT、DELETE。这些操作,OKHttp3都支持。但OKHttp3主要的特性为:同步、异步和拦截器。
一般来说,做服务器的,会较多考虑同步、异步、阻塞和非阻塞。但Android本身也不断升级,手机和电脑的鸿沟越来越小,Android本身也逐渐多出来异步操作。
同步操作为自己完成任务操作后一直等通知;异步操作意味着,自己并不关心任务的完成的过程,最后等任务到一档阶段后告知自己。同步完成是任务的常态。异步则一般通过消息队列来实现,等任务完成后,会通过回调函数解决该问题。
OKHttp3的同步和异步的例子如下:
// 同步操作
String url = "***自己的URL***";
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Call call = okHttpClient.newCall(request);
new Thread(new Runnable() {
@Override
public void run() {
try {
// 同步的关键是 call.execute()
Response response = call.execute();
Log.d(TAG, "run: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
// 异步操作
String url = "***自己的URL***";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
.url(url)
.get() //默认就是GET请求,可以不写
.build();
Call call = okHttpClient.newCall(request);
// 把请求加入消息队列
call.enqueue(new Callback() {
// 回调
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: ");
}
// 回调
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, "onResponse: " + response.body().string());
}
});
拦截器则是用来拦截HTTP请求,并在正式收发之前拦截到。样例如下:
// 拦截器程序
// 收发HTTP程序部分
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
Request request = new Request.Builder()
.url("***自己的URL***")
.header("User-Agent", "***自己的Header***")
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: " + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
if (body != null) {
Log.d(TAG, "onResponse: " + response.body().string());
body.close();
}
}
});
// 拦截器程序部分
public class LoggingInterceptor implements Interceptor {
private static final String TAG = "LoggingInterceptor";
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long startTime = System.nanoTime();
Log.d(TAG, String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long endTime = System.nanoTime();
Log.d(TAG, String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (endTime - startTime) / 1e6d, response.headers()));
return response;
}
}
引入OKHttp3的方法是:
implementation 'com.squareup.okhttp3:okhttp:4.4.1'//okHttp
在AndroidManifest.xml中添加网络权限(如有可以不添加)
<uses-permission android:name="android.permission.INTERNET" />
三、引论
OKHttp3是一个很好的HTTP工具,可以较好满足HTTP的收发;鉴于HTTP是最广泛应用的HTTP协议,可以采用OKHttp3。另外,学习和使用HTTP相关的包,了解HTTP永远是基础。