Android的网络请求(二)
okhttp工作原理
1.okhttp在发送请求时,会将请求发送到两个队列中(运行时队列和等待时队列),当运行时队列总数小于64并且访问同一目标机器请求小于5时请求会进入运行时队列,否则就进入等待时队列.
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
2.在请求进入运行时队列后,会立刻进入一个线程池,处理该请求.
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;
}
- 注意:在okhttp中线程池的等待队列(new SynchronousQueue())是一个空队列,所有进入该线程池的对象都会被立刻处理或抛出.
3.在每次请求被处理完后,会在符合上述条件下将等待时队列的请求转移到运行时队列中,并重复第一步中的操作
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.
}
}
建造者模式与责任链模式
1.建造者模式
- 定义:构建者(又称建造者)模式允许我们使用多个简单的对象一步一步构建成一个复杂的对象。
- 优点:使用时不需要关注所有的简单对象,因为在构建者模式中给我们提供了默认的值,只要修改需要定制的对象值就可以了.
- 缺点:会占用资源
okhttp中的例子:
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor().build();
代码中的addInterceptor()就是需要修改对象某一默认值时,调用的对应方法.
2.责任链模式
- 定义:为请求添加一个接收者对象的链,这种模式可以让请求的发送者和接收者进行解耦.在这种模式中,通常每个接收者都包含另一个接收者的引用,如果当前接收者无法处理该请求,则传递下一个接收者,以此类推.
okhttp中的例子:(在realcall的execute方法中调用了下面的方法)
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);
}