OkHttp作为主流的网络的请求框架,对其实现的流程有必要有一个大致的了解,
掌握了主线流程对理解整个OkHttp还是很有帮助的。先理解主干, 在理解分支。整个okhttp的网络请求精简下来也就只有如下几行。
private static void okhttpUseAction() {
// 构建者模式 --》 OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
// // 构建者模式 --》 Request
// GET请求
final Request request = new Request.Builder().url("https://www.baidu.com").get().build();
// Call call == RealCall
Call call = okHttpClient.newCall(request);
// 异步方法
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("请求失败.. E:" + e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String string = response.body().string();
System.out.println("请求完成.. result:" + string);
}
});
}
接下来根据上面的截图 以及代码分析具体的流程
第一步:
通过 构建者模式 创建Okhttp, 当然了,在创建OkHttpClient的时候,
可以在向Builder里面传递相关的配置
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
第二步
请求网络需要通过构建者模式构建一个Request,
其Builder有如下几个属性
public static class Builder {
HttpUrl url;
String method;
Headers.Builder headers;
RequestBody body;
Object tag;
}
可以得出该Builder主要是设置http请求的相关参数
故Request的创建方式如下:
Request request = new Request.Builder().url("https://www.baidu.com").get().build();
第三步
OkhttpClient 以及Request创建好了,接下来是拿OkHttp里面提供的Call实例
Call call = okHttpClient.newCall(request);
通过源码分析 得到call 是RealCall的一个实例
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
第四步
拿到Call的实例后,当然是去请求数据了, 这里分同步的去请求数据, 异步的请求数据
1.同步请求, call.excute()
2.异步请求, call.enqueue(Callback callback)
第五步
接下来主要分析 一下异步请求的流程
当调用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));
client.dispatcher()返回的是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);
}
}
上面的代码看到了executorService().execute(call); 这个类是通过线程池去加载数据
第七步
第六步是通过线程池去加载数据, 但是真正加载的代码是执行AsyncCall里面的run方法
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);
}
}
}
从上面的代码中看到了Response response = getResponseWithInterceptorChain();
这样就拿到了Response对象然后通过Callback回调回去
总结
通过上面的七步,对整个okhttp的主线流程有了一个大致的了解,
但是okHttp里面的内容远远不止这些,对于我自己而言。
还有如下几个问题:
1.OKHttp里面的线程池是用的哪一种
2.OkHttp里面经典的责任链模式是怎么实现的
3.OkHttp用到了哪些设计模式
4.OkHttp里面的拦截器是怎么实现的