官网介绍
HTTP是现代应用程序网络的方式。这就是我们交换数据和媒体的方式。有效地执行HTTP可使您的内容加载更快并节省带宽。
OkHttp是默认情况下有效的HTTP客户端:
- HTTP / 2支持允许对同一主机的所有请求共享一个套接字。
- 连接池可减少请求延迟(如果HTTP / 2不可用)。
- 透明的GZIP缩小了下载大小。
- 响应缓存可以完全避免网络重复请求。
使用
okhttp的使用就是下面这张图

1.创建OkHttpClient工厂(可以直接new也可以使用new OkHttpClient.Builder().build()方式构建,后者可以添加更多配置)
2.创建要发送的请求Request(指定post还是get 给定url 配置header等工作)
3.构建真正发送请求的Call(okHttpClient.newCall(request))
4.最后使用execute或enqueue发送请求(前者是同步后者是异步)
异步get
//异步get
public void AsynchronousGet() {
String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
//构建一个Request请求,在这里指定它的参数
Request request = new Request.Builder()
.url(url)
.get()//默认就是GET请求,可以不写
.build();
//使用OkHttpClient创建出真正可以执行Call
Call realCall = okHttpClient.newCall(request);
//发送异步请求
realCall.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());
}
});
}
这里的步骤和上面说的一样最后使用enqueue方法发送异步请求,请求处理在Callback回调类中的onResponse方法和onFailure方法做处理
同步get
public void SynchronousGet() {
String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
final Call call = okHttpClient.newCall(request);
new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = call.execute();
Log.d(TAG, "run: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
同步操作并没有很大区别,最后调用的是execute方法,这个方法不接受回调直接返回Response对象。注意的是这个同步操作不能在ui线程去做所以这里我开了个子线程.
post
public void post() {
//创建MediaType,用于描述请求/响应 body 的内容类型
MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
String msg = "I am shark.";
//创建RequestBody
RequestBody requestBody = RequestBody.create(mediaType, msg);
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(requestBody)
.build();
OkHttpClient okHttpClient = new OkHttpClient();
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 {
Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
Headers headers = response.headers();
for (int i = 0; i < headers.size(); i++) {
Log.d(TAG, headers.name(i) + ":" + headers.value(i));
}
Log.d(TAG, "onResponse: " + response.body().string());
}
});
}
post方法在构建Request的时候指定,它和get不同的是需要一个RequestBody 参数,这个参数我们可以使用RequestBody.create生成,它需要指定这个请求体的类型MediaType ,可以使用 MediaType.parse获得MediaType
post提交表单
//post提交表单
public void postForm() {
OkHttpClient okHttpClient = new OkHttpClient();
FormBody requestBody = new FormBody.Builder()
.add("testname", "testval")
.build();
Log.d(TAG, " requestBody.encodedName(0) " + requestBody.encodedName(0));
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(requestBody)
.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 {
Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
Headers headers = response.headers();
for (int i = 0; i < headers.size(); i++) {
Log.d(TAG, headers.name(i) + ":" + headers.value(i));
}
Log.d(TAG, "onResponse: " + response.body().string());
}
});
}
想要在post请求加入表单就要使用RequestBody的子类FormBody。Builder()方法后使用add("key","val")就能添加参数了。
再说明一点FormBody的name和val是存放在下面的两个List中的
public static final class Builder {
private final List<String> names = new ArrayList<>();
private final List<String> values = new ArrayList<>();
Interceptor拦截器
我们可以在一个请求发送前和发送后去拦截到它,并对其进行操作。这里okhttp3提供了Interceptor。这玩意很像struts2的拦截器。
首先我们自定义一个我们自己的拦截器,需要继承Interceptor
public class LoggingInterceptor implements Interceptor {
private static final String TAG = "LoggingInterceptor";
@Override
public Response intercept(Chain chain) throws IOException {
//获得Request
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 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;
}
}
调用chain.proceed(request)是每个拦截器实现的关键部分,它会继续我们请求的后续操作。这样在这之后的代码就是请求回来后才会执行的了。
在构建OkHttpClient的时候配置Interceptor
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
尾言
Okhttp3使用还是很简单的,不太清楚的地方可以查阅官方文档
https://square.github.io/okhttp/interceptors/
网友评论