// 构建okHttpClient,相当于请求的客户端,Builder设计模式
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(5, TimeUnit.SECONDS)
.build();
// 构建一个请求体,同样也是Builder设计模式
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
// 生成一个Call对象,该对象是接口类型,后面会说
Call call = okHttpClient.newCall(request);
try {
// 拿到Response
Response response = call.execute();
Log.i("TAG",response.body().string());
} catch (IOException e) {
}
- 通过Builder模式创建OkHttpClient对象和Request对象
- 调用OkHttpClient的newCall方法,获取一个Call对象,参数是Request
- 调用execute方法获取一个Respone
首先Builder是OkHttpClient一个静态内部类,在Builder的构造函数中进行了一系列的初始化操作。包括了对Dispatcher与ConnectionPool初始化。
Dispatcher分发器,负责将每一次Requst进行分发,压栈到自己的线程池,并通过调用者自己不同的方式进行异步和同步处理。
ConnectionPool是一个连接池对象,它可以用来管理连接对象,从它的构造方法中可以看到连接池的默认空闲连接数为5个,keepAlive时间为5分钟。
Call call = okHttpClient.newCall(request);
实际上创建的对象是Call的实现类RealCall 对象。
Response response = call.execute();
这里其实是调用的是RealCall类的execute()方法。
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
timeout.enter();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);//通过此方法将call对象放入到同步请求队列中。
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
e = timeoutExit(e);
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
在同步请求中Dispatcher主要负责了两件事,同步请求的保存和移除。
异步请求时client.newCall(request).enqueue();
RealCall.java
@Override public void enqueue(Callback responseCallback) {
//TODO 不能重复执行
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
//TODO 交给 dispatcher调度器 进行调度
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
利用dispatcher调度器,来进行实际的执行
client.dispatcher().enqueue(new AsyncCall(responseCallback));
在上面的OkHttpClient.Builder可以看出 已经初始化了Dispatcher。
//TODO 执行异步请求
synchronized void enqueue(AsyncCall call) {
//TODO 同时请求不能超过并发数(64,可配置调度器调整)
//TODO okhttp会使用共享主机即 地址相同的会共享socket
//TODO 同一个host最多允许5条线程通知执行请求
if (runningAsyncCalls.size() < maxRequests &&
runningCallsForHost(call) < maxRequestsPerHost) {
//TODO 加入运行队列 并交给线程池执行
runningAsyncCalls.add(