网上找了张图简单看一下整体流程:
OKhttp的post简单用法:
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
RequestBody requestBody = RequestBody.create(MediaType.parse(""), "content");
Request request = new Request.Builder().url("url").post(requestBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
分析一下这段代码都做了什么;
1:首先通过建造者模式初始化了OkHttpClient
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
通过上面代码可以看出,初始化一些默认值如超时时间,连接池等。
2:然后新建一个RequestBody。
public static RequestBody create(@Nullable MediaType contentType, String content) {
Charset charset = Util.UTF_8;
if (contentType != null) {
charset = contentType.charset();
if (charset == null) {
charset = Util.UTF_8;
contentType = MediaType.parse(contentType + "; charset=utf-8");
}
}
byte[] bytes = content.getBytes(charset);
return create(contentType, bytes);
}
RequestBody 这里主要确定传输数据类型和编码等。
3:新建一个Request对象
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tag = builder.tag != null ? builder.tag : this;
}
request中做了一些请求的参数,如请求头信息,请求路径请求参数等,并对参数做校验。
4:接下来Call call = okHttpClient.newCall(request),这个就通过之前的request来请求并回调数据。
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
实际上是调用了RealCall的newRealCall方法
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
返回一个call对象看一下源码对call对象的描述
A call is a request that has been prepared for execution.
意思就是等待指定的请求。
5:call.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));
}
主要代码是这句
client.dispatcher().enqueue(new AsyncCall(responseCallback));
调用了Dispatcher的enqueue方法。
那么什么是Dispatcher。
源码介绍 Policy on when async requests are executed.
意思大概就是 异步请求执行的决策者。
也就是说Dispatcher负责了线程的管理。
接下来看一下 Dispatcher下面enqueue方法
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
上面这段代码就是先判断了一下 当前的异步请求数量是否小于最大并发数。如果有等待的线程那么将请求添加到runningAsyncCalls 中否则等待添加到readyAsyncCalls中。
然后调用executorService().execute(call);方法来执行操作。
看一下 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;
}
这就是简单的基本调用流程。