okhttp3 的优点
1 内部封装了连接池减少请求延迟
2 对http2 协议进行了封装
3 分发器
4 拦截器
5 相应缓存避免重复请求
6 自动重定向
okhttp3 使用流程
OkHttpClient client = new OkHttpClient();
//POST方式提交String
MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
String requestBody = "I xxxxxx xxx";
Request request = new Request.Builder()
.url("http://xxx.xxx.xxx")
.addHeader("","")
.post(RequestBody.create(mediaType, requestBody))
.build();
//GET 请求
Request request2 = new Request.Builder()
.url("http://xxx.xxx.xxx")
.addHeader("","")
.get()//默认就是GET请求,可以不写
.build();
//POST提交文件
MediaType mediaType2 = MediaType.parse("text/x-markdown; charset=utf-8");
OkHttpClient okHttpClient = new OkHttpClient();
File file = new File("test.md");
Request request3 = new Request.Builder()
.url("http://xxx.xxx.xxx")
.post(RequestBody.create(mediaType, file))
.build();
//POST方式提交表单
RequestBody requestBody4 = new FormBody.Builder()
.add("search", "zxd")
.build();
Request request4 = new Request.Builder()
.url("http://xxx.xxx.xxx")
.post(requestBody4)
.build();
final Call call = client.newCall(request);
try {
//同步请求
new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
// 异步请求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().toString();
}
});
okhttp 分发器
// 创建Call 时 通过newCall 创建一个RealCall 的实例
final Call call = client.newCall(request);
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
// 异步请求 调用 RealCall 的 enqueue 方法
call.enqueue(new Callback() {
// 异步方法调用 OkHttpClient 的 dispatcher() Dispatcher类
// 也可以自定义 Dispatcher类
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
异步请求时 包含两个队列 runningAsyncCalls 和 readyAsyncCalls
同步请求时 包含一个队列 runningSyncCalls
/** Ready async calls in the order they'll be run. */
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
/** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
okhttp3 分发时首先判断 runningAsyncCalls 中的数量是否大于 最大请求数 ,
maxRequests 默认值 64 可修改
private int maxRequests = 64;
public synchronized void setMaxRequests(int maxRequests) {
if (maxRequests < 1) {
throw new IllegalArgumentException("max < 1: " + maxRequests);
}
this.maxRequests = maxRequests;
promoteCalls();
}
runningCallsForHost(call) < maxRequestsPerHost) {判断 同host 的请求数不超过 5 个
maxRequestsPerHost 默认值 5 可修改
private int maxRequestsPerHost = 5;
public synchronized void setMaxRequestsPerHost(int maxRequestsPerHost) {
if (maxRequestsPerHost < 1) {
throw new IllegalArgumentException("max < 1: " + maxRequestsPerHost);
}
this.maxRequestsPerHost = maxRequestsPerHost;
promoteCalls();
}
/** Returns the number of running calls that share a host with {@code call}. */
private int runningCallsForHost(AsyncCall call) {
int result = 0;
for (AsyncCall c : runningAsyncCalls) {
if (c.get().forWebSocket) continue;
if (c.host().equals(call.host())) result++;
}
return result;
}
1 当 runningAsyncCalls 队列数量大于 64
2 同类型服务器请求数量大于 5
readyAsyncCalls 队列添加数据
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
executorService() // 获取线程池
executorService().execute(call); //线程池执行 call 就是执行线程的 run 方法
AsyncCall call
final class AsyncCall extends NamedRunnable
ublic abstract class NamedRunnable implements Runnable {
@Override public final void run() {
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(name);
try {
execute();
} finally {
Thread.currentThread().setName(oldName);
}
}
protected abstract void execute();
所以最后会执行 AsyncCall 的 execute() 方法
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
}
发起 请求的返回 Response
Response response = getResponseWithInterceptorChain();
无论成功与否 最后都会执行 finished 方法
finally {
client.dispatcher().finished(this);
this 是 AsyncCall
}
/** Used by {@code AsyncCall#run} to signal completion. */
void finished(AsyncCall call) {
finished(runningAsyncCalls, call, true);
}
finished 方法中
1 calls.remove(call) 移除 runningAsyncCalls 中执行完成的 call
2 执行 promoteCalls(); 方法
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
if (promoteCalls) promoteCalls();
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
promoteCalls 方法中 ,先判断两个状态
1 runningAsyncCalls 运行队列的数量 是否大于 64
2 readyAsyncCalls 等待队列中是否为空
然后 迭代器迭代 readyAsyncCalls 等待队列
1 获取到等待的请求 ,在此判断 运行对列中 ,包含该服务器的请求的数量是否大于5
2 如果大于5 就 返回 不处理
3 小于5 等待队列删除该请求call
4 把该请求添加到 运行对列中 并执行
5 添加完之后继续判断 是否超过最大可执行数 64
private void promoteCalls() {
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
okhttp3 同步对列
阻塞执行
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
1 添加到同步对列中
/** Used by {@code Call#execute} to signal it is in-flight. */
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
2 进行请求
Response result = getResponseWithInterceptorChain();
3 返回
client.dispatcher().finished(this);
this 是 RealCall
/** Used by {@code Call#execute} to signal completion. */
void finished(RealCall call) {
finished(runningSyncCalls, call, false);
}
第三个参数传入 false
void finished(RealCall call) {
finished(runningSyncCalls, call, false);
}
所以在 finished 中 不走 promoteCalls()方法 跳过readyAsyncCalls对列的操作
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
if (promoteCalls) promoteCalls();
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
okhttp 的拦截器
拦截器入口
Response result = getResponseWithInterceptorChain();
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
1 添加自定义拦截器
interceptors.addAll(client.interceptors());
添加 retryAndFollowUpInterceptor拦截器 请求转发的内容
interceptors.add(retryAndFollowUpInterceptor);
添加 BridgeInterceptor拦截器 主要是处理 header头的内容
interceptors.add(new BridgeInterceptor(client.cookieJar()));
添加 CacheInterceptor拦截器 主要是处理缓存
interceptors.add(new CacheInterceptor(client.internalCache()));
添加 ConnectInterceptor拦截器 打开了与服务器的链接,正式开启了网络请求
interceptors.add(new ConnectInterceptor(client.cookieJar()));
添加 自定义WebSocket 相关拦截器
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
添加 CallServerInterceptor拦截器 向服务器发送请求,并最终返回Response对象供客户端使用。
interceptors.add(new CallServerInterceptor(client.cookieJar()));