[TOC]
1. 基础使用
1. 导入依赖
implementation 'com.squareup.okhttp3:okhttp:4.0.0'
2. 实现请求
public void netWork() {
//创建Get请求
Request getRequest = new Request.Builder().url("https://gank.io/api/v2/categories/GanHuo").build();
//创建Post请求
String params="xxxx";
MediaType mediaType = MediaType.parse("application/json");
Request postRequest = new Request.Builder().url("https://xxx.xxx.com/")
.post(RequestBody.create(params,mediaType)).build();
execute(getRequest);
enqueue(postRequest);
}
//异步请求
private void enqueue(Request request) {
new OkHttpClient().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
}
});
}
//同步请求
private void execute(Request request) {
try {
Response response = new OkHttpClient().newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
}
请求构成
简易流程图.png最少通过这四个角色进行一次完整的网络请求
- OkhttpClient 主角
- Request 请求对象
- Call 访问任务
- Response 响应对象
Dispatcher 与 Interceptors 无需关心即可使用,也可主动自定义进行配置
2. 分发器 Dispatcher--你的网络请求是如何被安排去请求的
流程简述:OkhttpClient在newCall调用时生成实际的realCall对象,在请求时,通过dispatch去真正安排执行请求。
//以下是异步请求的分发描述,同步请求不需要线程池也无限制,只需做下记录即可 private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>(); synchronized void executed(RealCall call) { runningSyncCalls.add(call); }
2.1 将请求交付Dispatcher
newCall.jpg enqueueCall.jpg2.2 Dispatcher内部分发
Dispatcher内部维护着两个队列
- 运行队列
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
存储正在运行的请求任务- 预备队列
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
存储将要运行的请求任务,当运行队列可放入时,从该队列中移动可放入的请求任务
2.2.1 放入
当满足运行队列小于限制的个数及同一个域名请求的个数小于限制时,将被放入运行队列,运行队列中的任务会被立刻执行;当不满足限制时,请求将会被放入准备队列,等待运行队列任务完成被移入
- private int maxRequests = 64;
- private int maxRequestsPerHost = 5;
2.2.2 执行
Dispatcher通过executorService().execute(call);
进行任务执行,实际是由内部的线程池完成执行
Dispatcher内部创建了线程池来对操作请求,通过设置核心线程为0,内部任务队列无容量来满足Okhttp的请求保持最大并发、无等待工作。 创建线程池.png任务执行完成时最终会回调Dispatcher的finished方法 回调finished.jpg
2.2.3 Finished,重新对队列操作
队列移动.jpg
- 先将已完成的任务移出运行队列
- 对预备队列中的任务做移入判定,满足限制时放入
这样就将所有的任务进行了分发
网友评论