基本使用
-
异步GET
Request.Builder builder = new Request.Builder().url("https://www.baidu.com/"); builder.method("GET",null); Request build = builder.build(); OkHttpClient client = new OkHttpClient(); Call call = client.newCall(build); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { System.out.println(response.body().string()); } });
-
异步POST
FormBody.Builder builder = new FormBody.Builder().add("XXX", "XXX"); FormBody build = builder.build(); Request request = new Request.Builder().url("https://.........").post(build).build(); OkHttpClient client = new OkHttpClient(); 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 { System.out.println(response.body().string()); } });
用法都非常简单,只用简单的调用一下,就能实现所想需要实现的GET,POST请求。
源码分析
我们还是从请求处理开始分析起:
Call call = client.newCall(request);
我们通常就会这样声明一个 Call 对象 然后执行异步 enqueue() 或者同步 execute()方法。
点进 newCall 里面:
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
这里实际就是返回了 RealCall 这个对象, 而接下来 网络请求 实际上就是调用 RealCall 的里面的方法。
分析 -- 异步enqueue()
@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));
}
从上面可以得知请求是从 dispatcher 完成的。
接下来分析 dispatcher
在 Dispatcher.java 下
先看看这个类所定义的变量吧
最大并发请求数
private int maxRequests = 64;
每个主机最大的请求数
private int maxRequestsPerHost = 5;
/** Executes calls. Created lazily. */
消费者线程池
private @Nullable ExecutorService executorService;
/** 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<>();
由此可以看出他维护个各种队列,把不同的Call放置相对应的队列中去,队列中的请求最后会一个个的进行访问。
接下来看看构造函数
/** Executes calls. Created lazily. */
private @Nullable ExecutorService executorService;
public Dispatcher(ExecutorService executorService) {
this.executorService = executorService;
}
public Dispatcher() {
}
构造函数有两个,一个构造函数是带参的,这个参数就是自己实现的线程池,如果我们调用不带参的构造函数时,executorService没有被初始化。而为他初始化的方法是 executorService () .
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
从上面看到他会创建一个默认的线程池 。
那么接下来在异步请求的时候会调用enqueue() 方法 ,而从下面我们可以看到 当异步请求队列 数量小于 64 并且正在运行的请求主机数小于5时,会把请求放置在 runningAsyncCalls 中 并在线程池中执行。 否则就加入到 readyAsyncCalls 中进行缓存。
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
然后就会执行以下方法
executorService().execute(call);
executorService()会返回一个线程池 , 如果使用的是默认线程池的话:那么在 ThreadPoolExecutor 内 ,所要传进去的是 Runnable 这个接口,
public void execute(Runnable command) {
.....
}
再看看 AsyncCall 这个类吧 :
AsyncCall 是 RealCall 的 内部类 。 他继承了NamedRunnable,而NamedRunnable正是实现了Runnable方法。
在NamedRunnable里面实现了run() 方法 ,run() 里面调用了他的一个 抽象方法 :
protected abstract void execute();
那么子类就只要实现 execute 方法就可以了:
所以就回到了 AsyncCall 中实现的 execute() 方法
@Override protected void execute() {
try{
......
} finally {
client.dispatcher().finished(this);
}
}
先来看看这个方法最后都做了什么吧 :
无论如何都会调用到 client.dispatcher().finished(this); 这个方法
进去 finished 方法 ,我们看到最后调用的方法为以下:
void finished(AsyncCall call) {
finished(runningAsyncCalls, call, true);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
注 1
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();
}
}
从上面可以看到 calls 是 runningAsyncCalls ,首先他先从队列移除,然后执行
promoteCalls() ,随后将更新 runningCallsCount 和 idleCallback 。
主要的方法就是 promoteCalls()
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.
}
}
从for语句可以明显看出 因为 runningAsyncCalls 的请求被移除了 , 那么就会从 readyAsyncCalls 中拿出请求向 runningAsyncCalls 补充 。
接着我们回到 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 就是请求的结果, 而网络请求交给了
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);
}
构建了一大堆拦截器,最后 创建了 RealInterceptorChain 这个 对象,他实际作用就是一个 拦截链 。
最后把请求交给了拦截链的proceed () 方法:
@Override public Response proceed(Request request) throws IOException {
return proceed(request, streamAllocation, httpCodec, connection);
}
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
.....
注 1
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
.....
return response;
}
注 1 : 从上面可以看出了这个拦截链会不断的调用下一个拦截器。从而现在分析一下所添加的拦截器吧。
在getResponseWithInterceptorChain() 方法中,里面就是添加了一堆拦截器
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));
在拿取拦截链里面的拦截器,然后一一执行。
retryAndFollowUpInterceptor -- 这拦截器主要是做重试,网络错误,以及请求重定向的一些操作。
BridgeInterceptor -- 这个拦截器,主要把用户的请求转换为网络的请求,负责对Request和Response报文进行加工。
CacheInterceptor -- 缓存拦截器
ConnectInterceptor -- 连接拦截器,主要是处理连接服务器,以及http , https的包装
CallServerInterceptor -- 服务拦截器,主要是发送(write、input)、读取(read、output)数据。也是拦截器的最后一个环节,这里就真正拿到了网络的结果了。
拦截器会不断的调用下一个拦截器,最后全部执行完。在每个拦截器里面,你可以看到类似的代码 : Response networkResponse = chain.proceed(...); 这就是调用了下一个拦截器。
拦截器所要执行的内容基本就如上的简述了。