okHttp源码分析
2020-04-26 本文已影响0人
卖炭少年炭治郎
okhttp版本
- implementation 'com.squareup.okhttp3:okhttp:3.10.0'
基本使用
String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
.url(url)
.get()//默认就是GET请求,可以不写
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, "onResponse: " + response.body().string());
}
});
源码分析
我们从调用的方式着手,看看代码是怎么走的
- 首先new OkHttpClient()这个对象,跟一下,看看构造方法里面干了什么?
public OkHttpClient() {
this(new Builder());
}
在new Builder()里面初始化了一些信息
public Builder() {
//这个是请求分发器,其实内部就是封装了线程池,但是new 里面是空实现
dispatcher = new Dispatcher();
//这个支持的协议 默认1.1 ,TLS1.2
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;
}
- 然后需要创建一个Request对象,可以看到这个类里面只是对url,请求头信息的一些存储。
- 通过okHttpClient.newCall(request),创建一个call对象。跟踪代码发现里面就是new RealCall()对象出来,RealCall实现了Cal接口。
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
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.enqueue()方法,就能拿到请求结果了。我们跟一下这个方法的实现
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
//最终会调用到分发器的enqueue方法
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
//加入到正在执行的队列里面
runningAsyncCalls.add(call);
//executorService()如果还没有创建线程池,就创建一个。执行这个runnable
executorService().execute(call);
} else {
//如果超过最大请求个数,就放到准备队列里面
readyAsyncCalls.add(call);
}
}
- client.dispatcher().enqueue(new AsyncCall(responseCallback)),我们看下AsyncCall的run方法干了什么?
发现AsyncCall并没有run方法,跟到父类里面NamedRunnable发现是执行了execute()方法
@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);
}
}
}
- getResponseWithInterceptorChain()方法里干了什么呢?
这就是okhttp的责任链机制,拦截,执行调用下个拦截,最终CallServerInterceptor里面实现网络请求拿到请求结果。
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);
}
我们也可以实现Interceptor接口,添加自己定义的拦截器,实现请求日志的打印。