请求/响应流程序分析
1、详解创建OkHttpClient
OkHttpClient mOkHttpClient = new OkHttpClient();
其主要调用
public OkHttpClient() {
this(new Builder());
}
这里通过静态内部类Builder实现OkHttpClient的构建
public Builder() {
//每一个Dispatcher都有一个线程池,用来分发异步请求
dispatcher = new Dispatcher();
//支持的协议,Http1.1 Http2.0
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、详解创建Request类实例
这个类其实作用很简单,就是代表一个HTTP请求
Request request = new Request.Builder()
.url("http://112.4.3.136:8080/portalone/homesdk/NetTVUniLogin")
.addHeader("name", "test")
.build();
其中Builder为Request的内部类
3、详解OkHttpClient实例调用newCall方法,返回Call
Call call = mOkHttpClient.newCall(request);
Call是一个接口,RealCall实现了这个接口,当调用newCall方法传入request参数的时候,实际上是返回一个RealCall。
4、详解Call的enqueue方法,将待执行请求放入到线程池
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
我们看下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));
}
AsyncCall是什么?
AsyncCall继承自NamedRunnable,NamedRunnable实现了Runnable接口
public abstract class NamedRunnable implements Runnable {
protected final String name;
public NamedRunnable(String format, Object... args) {
this.name = Util.format(format, args);
}
@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();
}
NamedRunnable每次执行的时候,都会调用抽象方法execute,则必然其子类在run的时候,execute也会被执行。最后会调用
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
到这里我们也得到几个新的知识点:
(1)OkHttp3支持的最大并发是64
(2)同一个Host支持的最大并发是5.
(3)调用call.enqueue的方法是异步发起Http请求。
(4)AsyncCall是RealCall的子类,RealCall是由Http请求Request创建出来的。
(5)AsyncCall继承自NamedRunnable, NamedRunnable实现了Runnable接口。
那如何发起一个同步的Http请求?
OkHttpClient mOkHttpClient = new OkHttpClient();
//new Request.Builder()实例化内部类
//通过build方法构建Request对象
Request request = new Request.Builder()
.url("http://112.4.3.136:8080/portalone/homesdk/NetTVUniLogin")
.addHeader("name", "test")
.build();
Call call = mOkHttpClient.newCall(request);
try {
//通过调用RealCall的execute去主动的发起一次请求
Response response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}