首先看下简单使用
1.github官网:https://square.github.io/okhttp/
2.添加依赖:compile ‘com.squareup.okhttp3:okhttp:3.10.0’
3.同步请求
OkHttpClient okHttpClient=new OkHttpClient.Builder().readTimeout(5000, TimeUnit.SECONDS).build();
public void synRequest(){
Request request=new Request.Builder().url("http://www.baidu.com")
.get()
.build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
同步问题:发送请求请求后,就会进入阻塞,直到接受到响应
4.异步请求
public void asyRequest() {
Request request = new Request.Builder().url("http://www.baidu.com")
.get()
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
//onFailure和onResponse都是运行在工作线程也就是子线程中
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println(response.body().string());
}
});
}
源码分析
okHttp框架同步请求流程和源码分析
1.OkHttpClient.Builder()方法中需要留意两个参数,builder方法主要用来放置参数
- dispatcher = new Dispatcher();事件分发器,主要判断异步是直接执行还是缓存执行
- connectionPool = new ConnectionPool();连接池
2.Request.Builder()方法源码分析
public Builder() {
//请求方法,默认是get请求
this.method = "GET";
//头部信息
this.headers = new Headers.Builder();
}
//builder方法
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
//new Request,设置参数为builder设置的参数
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;
}
3.Call call = okHttpClient.newCall(request);源码分析
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// 看RealCall方法
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
//将我们设置参数给RealCall
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
4. Response response = call.execute();源码分析
//会调用RealCall中的execute方法
Response execute() throws IOException;
@Override public Response execute() throws IOException {
synchronized (this) {
//判断当前是否已经执行过,如果已经执行过,抛出运行
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
//此调用无论同步还是异步在处理请求开始之前执行。
eventListener.callStart(this);
try {
//client.dispatcher()返回一个事件分发器,executed的目的就是将请求添加到同步请求队列中,自己看源码就知道了
client.dispatcher().executed(this);
//执行返回结果
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
//是将同步请求移除
client.dispatcher().finished(this);
}
}
client.dispatcher().finished(this);源码分析
void finished(RealCall call) {
//同步最后一个参数为false,异步最后一个参数为true
finished(runningSyncCalls, call, false);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
//因为是false所以下面方法不会执行
if (promoteCalls) promoteCalls();
//正在运行的数量=正在运行数量的同步的大小+正在运行异步数量的大小
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
至此同步请求源码分析结束
okHttp框架异步请求流程和源码分析
前三步和上面一样就不阐述了
call.enqueue源码分析
//RealCall中实现
void enqueue(Callback responseCallback);
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
//是否已经执行过,执行过返回异常
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
//之前同步的时候说了
eventListener.callStart(this);
//AsyncCall继承于NamedRunnable,而NamedRunnable实际继承与Runnable
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
synchronized void enqueue(AsyncCall call) {
//正在运行的大小小于最大请求 maxRequests =64
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
//将请求添加到正在运行的请求队列中
runningAsyncCalls.add(call);
//线程池去执行
executorService().execute(call);
} else {
//添加到已经准备的线程中
readyAsyncCalls.add(call);
}
}
executorService()
public synchronized ExecutorService executorService() {
if (executorService == null) {
//第一个参数核心线程数量,这里设置为0,目的是当空闲一段时间,将所有线程销毁
//Integer.MAX_VALUE为整形的最大值,不会印象性能,原因是OKHttp中设置了maxRequests=64
//第三个参数代表我们当前线程数大于核心线程数量时,最大空闲存活时间是60秒
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
executorService().execute(call);
//首先AsyncCall分析
final class AsyncCall extends NamedRunnable {}//看下NamedRunnalbe
//继承于runnable,也就是开了工作线程
public abstract class NamedRunnable implements Runnable {
@Override public final void run() {
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(name);
try {
execute();
} finally {
Thread.currentThread().setName(oldName);
}
}
//看下execute是哪个方法执行了 ,实际是RealCall执行了
protected abstract void execute();
}
execute
@Override protected void execute() {
boolean signalledCallback = false;
try {
//getResponseWithInterceptorChain接下来分析
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) {
} finally {
client.dispatcher().finished(this);
}
}
}
void finished(AsyncCall call) {
//之前同步也调用改方法,但是最后一个参数传的是false
finished(runningAsyncCalls, call, true);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
//正在运行的请求队列中移除改请求
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();
}
}
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.
}
}